mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-15 07:06:11 -04:00
Add cancel support for hotspot connection
PiperOrigin-RevId: 791394599
This commit is contained in:
committed by
Copybara-Service
parent
e66394d4f7
commit
0640a9c13c
@@ -12,9 +12,11 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#import <Foundation/Foundation.h> // NOLINT
|
||||
#import <Foundation/Foundation.h> // NOLINT
|
||||
#import <Network/Network.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class GNCIPv4Address;
|
||||
@class GNCHotspotSocket;
|
||||
|
||||
@@ -26,6 +28,14 @@
|
||||
*/
|
||||
@interface GNCHotspotMedium : NSObject
|
||||
|
||||
/**
|
||||
* Initializes the Hotspot medium with the specified queue.
|
||||
*
|
||||
* @param queue The queue to use for all internal operations.
|
||||
* @return An initialized Hotspot medium.
|
||||
*/
|
||||
- (instancetype)initWithQueue:(dispatch_queue_t)queue;
|
||||
|
||||
/**
|
||||
* Connects to a Wifi Hotspot with the specified SSID and password.
|
||||
*
|
||||
@@ -33,15 +43,14 @@
|
||||
* @param password The password of the Hotspot to connect to.
|
||||
* @return YES if the connection was successful, NO otherwise.
|
||||
*/
|
||||
- (BOOL)connectToWifiNetworkWithSSID:(nonnull NSString *)ssid
|
||||
password:(nonnull NSString *)password;
|
||||
- (BOOL)connectToWifiNetworkWithSSID:(NSString *)ssid password:(NSString *)password;
|
||||
|
||||
/**
|
||||
* Disconnects from a Wifi Hotspot with the specified SSID.
|
||||
*
|
||||
* @param ssid The SSID of the Hotspot to disconnect from.
|
||||
*/
|
||||
- (void) disconnectToWifiNetworkWithSSID:(nonnull NSString *)ssid;
|
||||
- (void)disconnectToWifiNetworkWithSSID:(NSString *)ssid;
|
||||
|
||||
/**
|
||||
* Gets the current Wifi SSID.
|
||||
@@ -58,8 +67,11 @@
|
||||
* @param[out] error Error that will be populated on failure.
|
||||
* @return Returns a connected socket or nil if an error has occurred.
|
||||
*/
|
||||
- (nullable GNCHotspotSocket *)connectToHost:(nonnull GNCIPv4Address *)host
|
||||
port:(NSInteger)port
|
||||
error:(NSError **_Nullable)error;
|
||||
- (nullable GNCHotspotSocket *)connectToHost:(GNCIPv4Address *)host
|
||||
port:(NSInteger)port
|
||||
cancelSource:(nullable dispatch_source_t)cancelSource
|
||||
error:(NSError *_Nullable *_Nullable)error;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCIPv4Address.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkError.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
// The maximum number of retries for connecting to the Hotspot.
|
||||
static const UInt8 kMaxRetryCount = 3;
|
||||
@@ -38,10 +40,23 @@ static const UInt8 kConnectionTimeoutInSeconds = 18;
|
||||
// An arbitrary timeout that should be pretty lenient.
|
||||
static const UInt8 kConnectionToHostTimeoutInSeconds = 10;
|
||||
|
||||
@implementation GNCHotspotMedium
|
||||
@implementation GNCHotspotMedium {
|
||||
dispatch_queue_t _hotspot_queue;
|
||||
}
|
||||
|
||||
- (BOOL)connectToWifiNetworkWithSSID:(nonnull NSString *)ssid
|
||||
password:(nonnull NSString *)password {
|
||||
- (instancetype)init {
|
||||
return [self initWithQueue:dispatch_get_main_queue()];
|
||||
}
|
||||
|
||||
- (instancetype)initWithQueue:(dispatch_queue_t)queue {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_hotspot_queue = queue;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)connectToWifiNetworkWithSSID:(NSString *)ssid password:(NSString *)password {
|
||||
#if TARGET_OS_IOS
|
||||
__block BOOL connected = NO;
|
||||
NEHotspotConfiguration *config = [[NEHotspotConfiguration alloc] initWithSSID:ssid
|
||||
@@ -98,7 +113,7 @@ static const UInt8 kConnectionToHostTimeoutInSeconds = 10;
|
||||
#endif // TARGET_OS_IOS
|
||||
}
|
||||
|
||||
- (void)disconnectToWifiNetworkWithSSID:(nonnull NSString *)ssid {
|
||||
- (void)disconnectToWifiNetworkWithSSID:(NSString *)ssid {
|
||||
#if TARGET_OS_IOS
|
||||
[[NEHotspotConfigurationManager sharedManager] removeConfigurationForSSID:ssid];
|
||||
#else
|
||||
@@ -106,9 +121,10 @@ static const UInt8 kConnectionToHostTimeoutInSeconds = 10;
|
||||
#endif // TARGET_OS_IOS
|
||||
}
|
||||
|
||||
- (GNCHotspotSocket *)connectToHost:(GNCIPv4Address *)host
|
||||
port:(NSInteger)port
|
||||
error:(NSError **)error {
|
||||
- (nullable GNCHotspotSocket *)connectToHost:(GNCIPv4Address *)host
|
||||
port:(NSInteger)port
|
||||
cancelSource:(nullable dispatch_source_t)cancelSource
|
||||
error:(NSError *_Nullable *_Nullable)error {
|
||||
// Validate host address
|
||||
if (!host.dottedRepresentation.UTF8String) {
|
||||
if (error) {
|
||||
@@ -122,12 +138,16 @@ static const UInt8 kConnectionToHostTimeoutInSeconds = 10;
|
||||
|
||||
nw_endpoint_t endpoint =
|
||||
nw_endpoint_create_host(host.dottedRepresentation.UTF8String, @(port).stringValue.UTF8String);
|
||||
return [self connectToEndpoint:endpoint includePeerToPeer:(BOOL)YES error:error];
|
||||
return [self connectToEndpoint:endpoint
|
||||
includePeerToPeer:(BOOL)YES
|
||||
cancelSource:cancelSource
|
||||
error:error];
|
||||
}
|
||||
|
||||
- (GNCHotspotSocket *)connectToEndpoint:(nw_endpoint_t)endpoint
|
||||
includePeerToPeer:(BOOL)includePeerToPeer
|
||||
error:(NSError **)error {
|
||||
- (nullable GNCHotspotSocket *)connectToEndpoint:(nw_endpoint_t)endpoint
|
||||
includePeerToPeer:(BOOL)includePeerToPeer
|
||||
cancelSource:(nullable dispatch_source_t)cancelSource
|
||||
error:(NSError *_Nullable *_Nullable)error {
|
||||
GNCLoggerInfo(@"connectToEndpoint: %@ includePeerToPeer: %d", endpoint.debugDescription,
|
||||
includePeerToPeer);
|
||||
|
||||
@@ -142,7 +162,7 @@ static const UInt8 kConnectionToHostTimeoutInSeconds = 10;
|
||||
nw_parameters_set_include_peer_to_peer(parameters, includePeerToPeer);
|
||||
nw_connection_t connection = nw_connection_create(endpoint, parameters);
|
||||
|
||||
nw_connection_set_queue(connection, dispatch_get_main_queue());
|
||||
nw_connection_set_queue(connection, _hotspot_queue);
|
||||
|
||||
nw_connection_set_state_changed_handler(
|
||||
connection, ^(nw_connection_state_t state, nw_error_t error) {
|
||||
@@ -159,6 +179,14 @@ static const UInt8 kConnectionToHostTimeoutInSeconds = 10;
|
||||
}
|
||||
});
|
||||
|
||||
if (cancelSource != nil) {
|
||||
dispatch_source_set_event_handler(cancelSource, ^{
|
||||
GNCLoggerWarning(@"connectToEndpoint is cancelled.");
|
||||
nw_connection_cancel(connection);
|
||||
dispatch_source_cancel(cancelSource);
|
||||
});
|
||||
}
|
||||
|
||||
nw_connection_start(connection);
|
||||
dispatch_time_t timeout =
|
||||
dispatch_time(DISPATCH_TIME_NOW, kConnectionToHostTimeoutInSeconds * NSEC_PER_SEC);
|
||||
@@ -249,3 +277,5 @@ static const UInt8 kConnectionToHostTimeoutInSeconds = 10;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -138,6 +138,7 @@ class WifiHotspotMedium : public api::WifiHotspotMedium {
|
||||
}
|
||||
|
||||
private:
|
||||
dispatch_queue_t hotspot_queue_ = nil;
|
||||
GNCHotspotMedium* medium_;
|
||||
NSString* hotspot_ssid_ = nil;
|
||||
};
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include "internal/platform/cancellation_flag_listener.h"
|
||||
#import "internal/platform/implementation/apple/Log/GNCLogger.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/Hotspot/GNCHotspotMedium.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/Hotspot/GNCHotspotSocket.h"
|
||||
@@ -28,6 +29,9 @@
|
||||
|
||||
namespace nearby {
|
||||
namespace apple {
|
||||
namespace {
|
||||
constexpr char kHotspotQueueLabel[] = "com.google.nearby.wifi_hotspot";
|
||||
}
|
||||
|
||||
#pragma mark - WifiHotspotInputStream
|
||||
|
||||
@@ -93,7 +97,11 @@ Exception WifiHotspotSocket::Close() {
|
||||
|
||||
#pragma mark - WifiHotspotMedium
|
||||
|
||||
WifiHotspotMedium::WifiHotspotMedium() : medium_([[GNCHotspotMedium alloc] init]) {} // NOLINT
|
||||
WifiHotspotMedium::WifiHotspotMedium() {
|
||||
hotspot_queue_ = dispatch_queue_create(kHotspotQueueLabel, DISPATCH_QUEUE_SERIAL);
|
||||
medium_ = [[GNCHotspotMedium alloc] initWithQueue:hotspot_queue_];
|
||||
}
|
||||
|
||||
WifiHotspotMedium::~WifiHotspotMedium() { DisconnectWifiHotspot(); }
|
||||
|
||||
bool WifiHotspotMedium::ConnectWifiHotspot(HotspotCredentials* hotspot_credentials_) {
|
||||
@@ -146,7 +154,29 @@ std::unique_ptr<api::WifiHotspotSocket> WifiHotspotMedium::ConnectToService(
|
||||
}
|
||||
GNCLoggerInfo(@"Connect to Hotspot host server: %@", [host dottedRepresentation]);
|
||||
|
||||
GNCHotspotSocket* socket = [medium_ connectToHost:host port:port error:&error];
|
||||
// Setup cancel listener
|
||||
std::unique_ptr<nearby::CancellationFlagListener> connection_cancellation_listener = nullptr;
|
||||
dispatch_source_t cancellation_source = nullptr;
|
||||
if (cancellation_flag != nullptr) {
|
||||
if (cancellation_flag->Cancelled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cancellation_source =
|
||||
dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, hotspot_queue_);
|
||||
|
||||
dispatch_resume(cancellation_source);
|
||||
connection_cancellation_listener = std::make_unique<nearby::CancellationFlagListener>(
|
||||
cancellation_flag, [&cancellation_source]() {
|
||||
GNCLoggerWarning(@"Cancelling to connect WiFi hotspot.");
|
||||
dispatch_source_merge_data(cancellation_source, 1);
|
||||
});
|
||||
}
|
||||
|
||||
GNCHotspotSocket* socket = [medium_ connectToHost:host
|
||||
port:port
|
||||
cancelSource:cancellation_source
|
||||
error:&error];
|
||||
if (socket != nil) {
|
||||
return std::make_unique<WifiHotspotSocket>(socket);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user