mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
[NC Apple coverage] Add tests for WifiHotspotMedium.
PiperOrigin-RevId: 820488585
This commit is contained in:
committed by
Copybara-Service
parent
d08ca79b89
commit
3569a9c17a
@@ -19,6 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class GNCIPv4Address;
|
||||
@class GNCHotspotSocket;
|
||||
@class GNCNWFramework;
|
||||
@class GNCNWFrameworkSocket;
|
||||
|
||||
/**
|
||||
@@ -37,6 +38,16 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (instancetype)initWithQueue:(dispatch_queue_t)queue;
|
||||
|
||||
/**
|
||||
* Initializes the Hotspot medium with the specified queue and network framework.
|
||||
*
|
||||
* @param queue The queue to use for all internal operations.
|
||||
* @param nwFramework The network framework to use for connections.
|
||||
* @return An initialized Hotspot medium.
|
||||
*/
|
||||
- (instancetype)initWithQueue:(dispatch_queue_t)queue
|
||||
nwFramework:(GNCNWFramework *)nwFramework NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Connects to a Wifi Hotspot with the specified SSID and password.
|
||||
*
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#import "internal/platform/implementation/apple/Log/GNCLogger.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCIPv4Address.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWConnectionImpl.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFramework.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkError.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.h"
|
||||
|
||||
@@ -55,6 +56,7 @@ static const UInt8 kConnectionToHostTimeoutInSeconds = 10;
|
||||
|
||||
@implementation GNCHotspotMedium {
|
||||
dispatch_queue_t _hotspot_queue;
|
||||
GNCNWFramework *_nwFramework;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
@@ -62,10 +64,15 @@ static const UInt8 kConnectionToHostTimeoutInSeconds = 10;
|
||||
}
|
||||
|
||||
- (instancetype)initWithQueue:(dispatch_queue_t)queue {
|
||||
return [self initWithQueue:queue nwFramework:[[GNCNWFramework alloc] init]];
|
||||
}
|
||||
|
||||
- (instancetype)initWithQueue:(dispatch_queue_t)queue nwFramework:(GNCNWFramework *)nwFramework {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_hotspot_queue = queue;
|
||||
_locationManager = [[CLLocationManager alloc] init];
|
||||
_nwFramework = nwFramework;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -238,90 +245,12 @@ static const UInt8 kConnectionToHostTimeoutInSeconds = 10;
|
||||
return nil;
|
||||
}
|
||||
|
||||
nw_endpoint_t endpoint =
|
||||
nw_endpoint_create_host(host.dottedRepresentation.UTF8String, @(port).stringValue.UTF8String);
|
||||
return [self connectToEndpoint:endpoint
|
||||
includePeerToPeer:(BOOL)YES
|
||||
cancelSource:cancelSource
|
||||
error:error];
|
||||
}
|
||||
|
||||
- (nullable GNCNWFrameworkSocket *)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);
|
||||
|
||||
dispatch_semaphore_t semaphore_internal = dispatch_semaphore_create(0);
|
||||
__block nw_connection_state_t blockResult = nw_connection_state_invalid;
|
||||
__block NSError *blockError = nil;
|
||||
|
||||
nw_parameters_t parameters =
|
||||
nw_parameters_create_secure_tcp(/*tls*/ NW_PARAMETERS_DISABLE_PROTOCOL,
|
||||
/*tcp*/ NW_PARAMETERS_DEFAULT_CONFIGURATION);
|
||||
|
||||
nw_parameters_set_include_peer_to_peer(parameters, includePeerToPeer);
|
||||
nw_connection_t connection = nw_connection_create(endpoint, parameters);
|
||||
|
||||
nw_connection_set_queue(connection, _hotspot_queue);
|
||||
|
||||
nw_connection_set_state_changed_handler(
|
||||
connection, ^(nw_connection_state_t state, nw_error_t error) {
|
||||
GNCLoggerDebug(@"connectToEndpoint state changed to: %d", state);
|
||||
|
||||
// Ignore the preparing state and waiting state, because it is not a final state.
|
||||
if ((state != nw_connection_state_preparing) && (state != nw_connection_state_waiting)) {
|
||||
blockResult = state;
|
||||
if (error != nil) {
|
||||
GNCLoggerError(@"connectToEndpoint Error: %@", error.debugDescription);
|
||||
blockError = (__bridge_transfer NSError *)nw_error_copy_cf_error(error);
|
||||
}
|
||||
dispatch_semaphore_signal(semaphore_internal);
|
||||
}
|
||||
});
|
||||
|
||||
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);
|
||||
if (dispatch_semaphore_wait(semaphore_internal, timeout) != 0) {
|
||||
GNCLoggerError(@"Connecting to %@ timeout in %d seconds", endpoint.debugDescription,
|
||||
kConnectionToHostTimeoutInSeconds);
|
||||
nw_connection_set_state_changed_handler(connection, nil); // Prevent callback issues
|
||||
nw_connection_cancel(connection);
|
||||
if (error != nil) {
|
||||
*error = [NSError errorWithDomain:GNCNWFrameworkErrorDomain
|
||||
code:GNCNWFrameworkErrorTimedOut
|
||||
userInfo:nil];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (error != nil) {
|
||||
*error = blockError;
|
||||
}
|
||||
|
||||
switch (blockResult) {
|
||||
case nw_connection_state_invalid:
|
||||
case nw_connection_state_waiting:
|
||||
case nw_connection_state_preparing:
|
||||
case nw_connection_state_failed:
|
||||
case nw_connection_state_cancelled:
|
||||
GNCLoggerError(@"connectToEndpoint failed with result: %d", blockResult);
|
||||
return nil;
|
||||
case nw_connection_state_ready: {
|
||||
return [[GNCNWFrameworkSocket alloc]
|
||||
initWithConnection:[[GNCNWConnectionImpl alloc] initWithNWConnection:connection]];
|
||||
}
|
||||
}
|
||||
return [_nwFramework connectToHost:host
|
||||
port:port
|
||||
includePeerToPeer:YES
|
||||
cancelSource:cancelSource
|
||||
queue:_hotspot_queue
|
||||
error:error];
|
||||
}
|
||||
|
||||
- (NSString *)getCurrentWifiSSID {
|
||||
|
||||
@@ -156,12 +156,17 @@ typedef void (^ServiceUpdateHandler)(NSString *_Nonnull serviceName,
|
||||
* @param host The IPv4 address to connect to.
|
||||
* @param port The port to connect to.
|
||||
* @param includePeerToPeer Whether to include peer-to-peer services.
|
||||
* @param cancelSource An optional dispatch source to cancel the connection attempt.
|
||||
* @param queue An optional dispatch queue to use for connection events. If nil, the main queue is
|
||||
* used.
|
||||
* @param[out] error Error that will be populated on failure.
|
||||
* @return Returns a connected socket or nil if an error has occured.
|
||||
*/
|
||||
- (nullable GNCNWFrameworkSocket *)connectToHost:(GNCIPv4Address *)host
|
||||
port:(NSInteger)port
|
||||
includePeerToPeer:(BOOL)includePeerToPeer
|
||||
cancelSource:(nullable dispatch_source_t)cancelSource
|
||||
queue:(nullable dispatch_queue_t)queue
|
||||
error:(NSError **_Nullable)error;
|
||||
|
||||
/**
|
||||
|
||||
@@ -69,6 +69,9 @@ NSDictionary<NSString *, NSString *> *GNCTXTRecordForBrowseResult(nw_browse_resu
|
||||
PSKIdentity:(nullable NSData *)PSKIdentity
|
||||
PSKSharedSecret:(nullable NSData *)PSKSharedSecret
|
||||
includePeerToPeer:(BOOL)includePeerToPeer
|
||||
cancelSource:
|
||||
(nullable dispatch_source_t)cancelSource
|
||||
queue:(nullable dispatch_queue_t)queue
|
||||
error:(NSError **)error;
|
||||
@end
|
||||
|
||||
@@ -319,6 +322,8 @@ NSDictionary<NSString *, NSString *> *GNCTXTRecordForBrowseResult(nw_browse_resu
|
||||
PSKIdentity:nil
|
||||
PSKSharedSecret:nil
|
||||
includePeerToPeer:_includePeerToPeer
|
||||
cancelSource:nil
|
||||
queue:nil
|
||||
error:error];
|
||||
}
|
||||
|
||||
@@ -336,12 +341,16 @@ NSDictionary<NSString *, NSString *> *GNCTXTRecordForBrowseResult(nw_browse_resu
|
||||
PSKIdentity:PSKIdentity
|
||||
PSKSharedSecret:PSKSharedSecret
|
||||
includePeerToPeer:_includePeerToPeer
|
||||
cancelSource:nil
|
||||
queue:nil
|
||||
error:error];
|
||||
}
|
||||
|
||||
- (nullable GNCNWFrameworkSocket *)connectToHost:(GNCIPv4Address *)host
|
||||
port:(NSInteger)port
|
||||
includePeerToPeer:(BOOL)includePeerToPeer
|
||||
cancelSource:(nullable dispatch_source_t)cancelSource
|
||||
queue:(nullable dispatch_queue_t)queue
|
||||
error:(NSError **)error {
|
||||
GNCLoggerInfo(@"[GNCNWFramework] Connect to host {host:%s, port:%ld}.",
|
||||
host.dottedRepresentation.UTF8String, (long)port);
|
||||
@@ -351,6 +360,8 @@ NSDictionary<NSString *, NSString *> *GNCTXTRecordForBrowseResult(nw_browse_resu
|
||||
PSKIdentity:nil
|
||||
PSKSharedSecret:nil
|
||||
includePeerToPeer:(BOOL)includePeerToPeer
|
||||
cancelSource:cancelSource
|
||||
queue:queue
|
||||
error:error];
|
||||
}
|
||||
|
||||
@@ -360,6 +371,9 @@ NSDictionary<NSString *, NSString *> *GNCTXTRecordForBrowseResult(nw_browse_resu
|
||||
PSKIdentity:(nullable NSData *)PSKIdentity
|
||||
PSKSharedSecret:(nullable NSData *)PSKSharedSecret
|
||||
includePeerToPeer:(BOOL)includePeerToPeer
|
||||
cancelSource:
|
||||
(nullable dispatch_source_t)cancelSource
|
||||
queue:(nullable dispatch_queue_t)queue
|
||||
error:(NSError **)error {
|
||||
NSCondition *condition = [[NSCondition alloc] init];
|
||||
[condition lock];
|
||||
@@ -378,7 +392,7 @@ NSDictionary<NSString *, NSString *> *GNCTXTRecordForBrowseResult(nw_browse_resu
|
||||
return nil;
|
||||
}
|
||||
nw_connection_t connection = nw_connection_create(endpoint, parameters);
|
||||
nw_connection_set_queue(connection, dispatch_get_main_queue());
|
||||
nw_connection_set_queue(connection, queue ? queue : dispatch_get_main_queue());
|
||||
nw_connection_set_state_changed_handler(
|
||||
connection, ^(nw_connection_state_t state, nw_error_t error) {
|
||||
[condition lock];
|
||||
@@ -392,6 +406,14 @@ NSDictionary<NSString *, NSString *> *GNCTXTRecordForBrowseResult(nw_browse_resu
|
||||
}
|
||||
[condition unlock];
|
||||
});
|
||||
if (cancelSource) {
|
||||
dispatch_source_set_event_handler(cancelSource, ^{
|
||||
GNCLoggerInfo(
|
||||
@"[GNCNWFramework] Connection to endpoint was cancelled before it could be established.");
|
||||
nw_connection_cancel(connection);
|
||||
dispatch_source_cancel(cancelSource);
|
||||
});
|
||||
}
|
||||
nw_connection_start(connection);
|
||||
|
||||
BOOL didSignal =
|
||||
|
||||
+4
-2
@@ -38,8 +38,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property(nonatomic) BOOL connectedToIncludePeerToPeer;
|
||||
@property(nonatomic) NSInteger listenedForServiceOnPort;
|
||||
@property(nonatomic) BOOL listenedForServiceIncludePeerToPeer;
|
||||
@property(nonatomic, readonly) NSMutableArray<GNCFakeNWFrameworkSocket *>* sockets;
|
||||
@property(nonatomic, readonly) NSMutableArray<GNCFakeNWFrameworkServerSocket *>* serverSockets;
|
||||
@property(nonatomic, readonly) NSMutableArray<GNCFakeNWFrameworkSocket*>* sockets;
|
||||
@property(nonatomic, readonly) NSMutableArray<GNCFakeNWFrameworkServerSocket*>* serverSockets;
|
||||
@property(nonatomic, nullable) dispatch_source_t connectedWithCancelSource;
|
||||
@property(nonatomic, nullable) dispatch_queue_t connectedWithQueue;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
+10
-6
@@ -60,8 +60,8 @@
|
||||
error:(NSError **)error {
|
||||
self.connectedToServiceName = serviceName;
|
||||
self.connectedToServiceType = serviceType;
|
||||
GNCFakeNWFrameworkSocket *socket = [[GNCFakeNWFrameworkSocket alloc]
|
||||
initWithConnection:[[GNCFakeNWConnection alloc] init]];
|
||||
GNCFakeNWFrameworkSocket *socket =
|
||||
[[GNCFakeNWFrameworkSocket alloc] initWithConnection:[[GNCFakeNWConnection alloc] init]];
|
||||
[self.sockets addObject:socket];
|
||||
return socket;
|
||||
}
|
||||
@@ -73,8 +73,8 @@
|
||||
error:(NSError **)error {
|
||||
self.connectedToServiceName = serviceName;
|
||||
self.connectedToServiceType = serviceType;
|
||||
GNCFakeNWFrameworkSocket *socket = [[GNCFakeNWFrameworkSocket alloc]
|
||||
initWithConnection:[[GNCFakeNWConnection alloc] init]];
|
||||
GNCFakeNWFrameworkSocket *socket =
|
||||
[[GNCFakeNWFrameworkSocket alloc] initWithConnection:[[GNCFakeNWConnection alloc] init]];
|
||||
[self.sockets addObject:socket];
|
||||
return socket;
|
||||
}
|
||||
@@ -82,12 +82,16 @@
|
||||
- (GNCNWFrameworkSocket *)connectToHost:(GNCIPv4Address *)host
|
||||
port:(NSInteger)port
|
||||
includePeerToPeer:(BOOL)includePeerToPeer
|
||||
cancelSource:(nullable dispatch_source_t)cancelSource
|
||||
queue:(nullable dispatch_queue_t)queue
|
||||
error:(NSError **)error {
|
||||
self.connectedToHost = host;
|
||||
self.connectedToPort = port;
|
||||
self.connectedToIncludePeerToPeer = includePeerToPeer;
|
||||
GNCFakeNWFrameworkSocket *socket = [[GNCFakeNWFrameworkSocket alloc]
|
||||
initWithConnection:[[GNCFakeNWConnection alloc] init]];
|
||||
self.connectedWithCancelSource = cancelSource;
|
||||
self.connectedWithQueue = queue;
|
||||
GNCFakeNWFrameworkSocket *socket =
|
||||
[[GNCFakeNWFrameworkSocket alloc] initWithConnection:[[GNCFakeNWConnection alloc] init]];
|
||||
[self.sockets addObject:socket];
|
||||
return socket;
|
||||
}
|
||||
|
||||
+5
-1
@@ -12,8 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWConnection.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWConnection.h"
|
||||
|
||||
@implementation GNCFakeNWFrameworkSocket
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
if (self.dataToRead) {
|
||||
NSData *data = self.dataToRead;
|
||||
self.dataToRead = nil;
|
||||
if (data.length > length) {
|
||||
self.dataToRead = [data subdataWithRange:NSMakeRange(length, data.length - length)];
|
||||
return [data subdataWithRange:NSMakeRange(0, length)];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
return [NSData data];
|
||||
|
||||
@@ -35,6 +35,7 @@ objc_library(
|
||||
"GNCSingleThreadExecutorTest.mm",
|
||||
"GNCTimerTest.mm",
|
||||
"GNCUtilsTest.m",
|
||||
"GNCWifiHotspotMediumTest.mm",
|
||||
"GNCWifiLanMediumTest.mm",
|
||||
"UtilsTest.mm",
|
||||
"ble_medium_test.mm",
|
||||
@@ -51,6 +52,8 @@ objc_library(
|
||||
"//internal/platform/implementation/apple:ble_v2",
|
||||
"//internal/platform/implementation/apple/Mediums/BLE",
|
||||
"//internal/platform/implementation/apple/Mediums/BLE/Tests:BLETestsLib",
|
||||
"//internal/platform/implementation/apple/Mediums/CoreLocation/CLLocationManager/Fake",
|
||||
"//internal/platform/implementation/apple/Mediums/Hotspot",
|
||||
"//internal/platform/implementation/apple/Mediums/WiFiCommon",
|
||||
"//internal/platform/implementation/apple/Mediums/WiFiCommon/Tests:FakeNWFramework",
|
||||
"//third_party/apple_frameworks:CommonCrypto",
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/platform/implementation/apple/wifi_hotspot.h"
|
||||
|
||||
#import <CoreLocation/CoreLocation.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/CoreLocation/CLLocationManager/Fake/CLLocationManagerFake.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/Hotspot/GNCHotspotMedium.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCIPv4Address.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFramework.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFramework.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkServerSocket.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/Tests/GNCFakeNWFrameworkSocket.h"
|
||||
|
||||
namespace {
|
||||
const int kPort = 1234;
|
||||
const char kIPAddress[] = "192.168.1.2";
|
||||
} // namespace
|
||||
|
||||
// Expose for testing
|
||||
@interface GNCHotspotMedium (Testing)
|
||||
@property(nonatomic) CLLocationManager *locationManager;
|
||||
@end
|
||||
|
||||
@interface GNCWifiHotspotMediumTest : XCTestCase
|
||||
@end
|
||||
|
||||
@implementation GNCWifiHotspotMediumTest {
|
||||
GNCFakeNWFramework *_fakeNWFramework;
|
||||
GNCHotspotMedium *_medium;
|
||||
CLLocationManagerFake *_fakeLocationManager;
|
||||
std::unique_ptr<nearby::apple::WifiHotspotMedium> _hotspotMedium;
|
||||
}
|
||||
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
_fakeNWFramework = [[GNCFakeNWFramework alloc] init];
|
||||
_medium = [[GNCHotspotMedium alloc] initWithQueue:dispatch_get_main_queue()
|
||||
nwFramework:_fakeNWFramework];
|
||||
_fakeLocationManager = [[CLLocationManagerFake alloc] init];
|
||||
_medium.locationManager = _fakeLocationManager;
|
||||
_hotspotMedium = std::make_unique<nearby::apple::WifiHotspotMedium>(_medium);
|
||||
}
|
||||
|
||||
- (void)tearDown {
|
||||
_hotspotMedium.reset();
|
||||
_fakeNWFramework = nil;
|
||||
_medium = nil;
|
||||
_fakeLocationManager = nil;
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testConnectWifiHotspot {
|
||||
nearby::HotspotCredentials hotspotCredentials;
|
||||
hotspotCredentials.SetSSID("TestSSID");
|
||||
hotspotCredentials.SetPassword("TestPassword");
|
||||
|
||||
XCTAssertFalse(_hotspotMedium->ConnectWifiHotspot(&hotspotCredentials));
|
||||
}
|
||||
|
||||
- (void)testListenForService {
|
||||
// iOS does not support acting as a Wifi Hotspot server.
|
||||
XCTAssertTrue(_hotspotMedium->ListenForService(1234) == nullptr);
|
||||
}
|
||||
|
||||
- (void)testConnectToService {
|
||||
nearby::CancellationFlag cancellationFlag;
|
||||
|
||||
std::unique_ptr<nearby::api::WifiHotspotSocket> socket =
|
||||
_hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag);
|
||||
|
||||
XCTAssertTrue(socket != nullptr);
|
||||
XCTAssertEqualObjects(_fakeNWFramework.connectedToHost.dottedRepresentation,
|
||||
[NSString stringWithUTF8String:kIPAddress]);
|
||||
XCTAssertEqual(_fakeNWFramework.connectedToPort, kPort);
|
||||
XCTAssertTrue(_fakeNWFramework.connectedToIncludePeerToPeer);
|
||||
}
|
||||
|
||||
- (void)testInputStreamRead {
|
||||
nearby::CancellationFlag cancellationFlag;
|
||||
std::unique_ptr<nearby::api::WifiHotspotSocket> socket =
|
||||
_hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag);
|
||||
GNCFakeNWFrameworkSocket *fakeSocket = _fakeNWFramework.sockets.firstObject;
|
||||
NSData *data = [@"TestData" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
fakeSocket.dataToRead = data;
|
||||
|
||||
nearby::ExceptionOr<nearby::ByteArray> readData = socket->GetInputStream().Read(4);
|
||||
|
||||
XCTAssertTrue(readData.ok());
|
||||
XCTAssertEqual(readData.result().size(), 4);
|
||||
XCTAssertEqual(strncmp(readData.result().data(), "Test", 4), 0);
|
||||
}
|
||||
|
||||
- (void)testInputStreamClose {
|
||||
nearby::CancellationFlag cancellationFlag;
|
||||
std::unique_ptr<nearby::api::WifiHotspotSocket> socket =
|
||||
_hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag);
|
||||
GNCFakeNWFrameworkSocket *fakeSocket = _fakeNWFramework.sockets.firstObject;
|
||||
|
||||
nearby::Exception closeResult = socket->GetInputStream().Close();
|
||||
|
||||
XCTAssertTrue(closeResult.Ok());
|
||||
XCTAssertFalse(fakeSocket.isClosed);
|
||||
}
|
||||
|
||||
- (void)testOutputStreamWrite {
|
||||
nearby::CancellationFlag cancellationFlag;
|
||||
std::unique_ptr<nearby::api::WifiHotspotSocket> socket =
|
||||
_hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag);
|
||||
GNCFakeNWFrameworkSocket *fakeSocket = _fakeNWFramework.sockets.firstObject;
|
||||
NSData *data = [@"TestData" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
nearby::ByteArray byteArray(reinterpret_cast<const char *>(data.bytes), data.length);
|
||||
|
||||
nearby::Exception writeResult = socket->GetOutputStream().Write(byteArray);
|
||||
|
||||
XCTAssertTrue(writeResult.Ok());
|
||||
XCTAssertEqualObjects(fakeSocket.writtenData, data);
|
||||
}
|
||||
|
||||
- (void)testSocketClose {
|
||||
nearby::CancellationFlag cancellationFlag;
|
||||
std::unique_ptr<nearby::api::WifiHotspotSocket> socket =
|
||||
_hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag);
|
||||
GNCFakeNWFrameworkSocket *fakeSocket = _fakeNWFramework.sockets.firstObject;
|
||||
|
||||
nearby::Exception closeResult = socket->Close();
|
||||
|
||||
XCTAssertTrue(closeResult.Ok());
|
||||
XCTAssertTrue(fakeSocket.isClosed);
|
||||
}
|
||||
|
||||
- (void)testOutputStreamFlush {
|
||||
nearby::CancellationFlag cancellationFlag;
|
||||
std::unique_ptr<nearby::api::WifiHotspotSocket> socket =
|
||||
_hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag);
|
||||
|
||||
nearby::Exception flushResult = socket->GetOutputStream().Flush();
|
||||
|
||||
XCTAssertTrue(flushResult.Ok());
|
||||
}
|
||||
|
||||
- (void)testOutputStreamClose {
|
||||
nearby::CancellationFlag cancellationFlag;
|
||||
std::unique_ptr<nearby::api::WifiHotspotSocket> socket =
|
||||
_hotspotMedium->ConnectToService(kIPAddress, kPort, &cancellationFlag);
|
||||
GNCFakeNWFrameworkSocket *fakeSocket = _fakeNWFramework.sockets.firstObject;
|
||||
|
||||
nearby::Exception closeResult = socket->GetOutputStream().Close();
|
||||
|
||||
XCTAssertTrue(closeResult.Ok());
|
||||
XCTAssertFalse(fakeSocket.isClosed);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -153,6 +153,8 @@ GNCNWFrameworkSocket* ConnectToService(GNCNWFramework* medium, const std::string
|
||||
GNCNWFrameworkSocket* socket = [medium connectToHost:host
|
||||
port:port
|
||||
includePeerToPeer:include_peer_to_peer
|
||||
cancelSource:nil
|
||||
queue:nil
|
||||
error:&error];
|
||||
if (socket != nil) {
|
||||
return socket;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef PLATFORM_IMPL_APPLE_WIFI_HOTSPOT_H_
|
||||
#define PLATFORM_IMPL_APPLE_WIFI_HOTSPOT_H_
|
||||
|
||||
#import <Foundation/Foundation.h> // NOLINT
|
||||
#import <Foundation/Foundation.h> // NOLINT
|
||||
#import <Network/Network.h>
|
||||
|
||||
#include <string>
|
||||
@@ -27,6 +27,7 @@
|
||||
@class GNCMBonjourService;
|
||||
@class GNCHotspotMedium;
|
||||
@class GNCNWFrameworkSocket;
|
||||
@class GNCNWFrameworkServerSocket;
|
||||
|
||||
namespace nearby {
|
||||
namespace apple {
|
||||
@@ -68,7 +69,6 @@ class WifiHotspotOutputStream : public OutputStream {
|
||||
class WifiHotspotSocket : public api::WifiHotspotSocket {
|
||||
public:
|
||||
explicit WifiHotspotSocket(GNCNWFrameworkSocket* socket);
|
||||
explicit WifiHotspotSocket() = default;
|
||||
~WifiHotspotSocket() override = default;
|
||||
InputStream& GetInputStream() override;
|
||||
OutputStream& GetOutputStream() override;
|
||||
@@ -86,6 +86,8 @@ class WifiHotspotSocket : public api::WifiHotspotSocket {
|
||||
class WifiHotspotMedium : public api::WifiHotspotMedium {
|
||||
public:
|
||||
WifiHotspotMedium();
|
||||
// For testing only.
|
||||
explicit WifiHotspotMedium(GNCHotspotMedium* hotspot_medium);
|
||||
~WifiHotspotMedium() override;
|
||||
|
||||
WifiHotspotMedium(const WifiHotspotMedium&) = delete;
|
||||
@@ -121,10 +123,11 @@ class WifiHotspotMedium : public api::WifiHotspotMedium {
|
||||
absl::string_view ip_address, int port, CancellationFlag* cancellation_flag) override;
|
||||
|
||||
// IOS is not supporting WifiHotspot Server yet.
|
||||
bool StartWifiHotspot(HotspotCredentials* hotspot_credentials) override {return false;}
|
||||
bool StopWifiHotspot() override {return false;}
|
||||
std::unique_ptr<api::WifiHotspotServerSocket> ListenForService(
|
||||
int port) override { return nil; }
|
||||
bool StartWifiHotspot(HotspotCredentials* hotspot_credentials) override { return false; }
|
||||
bool StopWifiHotspot() override { return false; }
|
||||
std::unique_ptr<api::WifiHotspotServerSocket> ListenForService(int port) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the dynamic port range for the Wifi Hotspot.
|
||||
@@ -132,8 +135,7 @@ class WifiHotspotMedium : public api::WifiHotspotMedium {
|
||||
* @return An optional pair of integers representing the minimum and maximum dynamic port numbers,
|
||||
* or absl::nullopt if not supported.
|
||||
*/
|
||||
std::optional<std::pair<std::int32_t, std::int32_t>> GetDynamicPortRange()
|
||||
override {
|
||||
std::optional<std::pair<std::int32_t, std::int32_t>> GetDynamicPortRange() override {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,10 @@
|
||||
#import "internal/platform/implementation/apple/Log/GNCLogger.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/Hotspot/GNCHotspotMedium.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCIPv4Address.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFramework.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkServerSocket.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/WiFiCommon/GNCNWFrameworkSocket.h"
|
||||
#import "internal/platform/implementation/apple/network_utils.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace apple {
|
||||
@@ -103,6 +106,8 @@ WifiHotspotMedium::WifiHotspotMedium() {
|
||||
medium_ = [[GNCHotspotMedium alloc] initWithQueue:hotspot_queue_];
|
||||
}
|
||||
|
||||
WifiHotspotMedium::WifiHotspotMedium(GNCHotspotMedium* hotspot_medium) : medium_(hotspot_medium) {}
|
||||
|
||||
WifiHotspotMedium::~WifiHotspotMedium() { DisconnectWifiHotspot(); }
|
||||
|
||||
bool WifiHotspotMedium::ConnectWifiHotspot(HotspotCredentials* hotspot_credentials_) {
|
||||
|
||||
Reference in New Issue
Block a user