mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Refactor GATT/L2CAP servers to support shared peripheral manager
PiperOrigin-RevId: 882024313
This commit is contained in:
committed by
Lasan Mahaliyana
parent
840d24896f
commit
2f6cff0f08
@@ -104,6 +104,10 @@ constexpr auto kMediumMaxAllowedReadBytes =
|
||||
// Disable/Enable refactor of BLE/L2CAP in Nearby Connections SDK.
|
||||
constexpr auto kRefactorBleL2cap =
|
||||
flags::Flag<bool>(kConfigPackage, "45737079", false);
|
||||
// Enable/Disable usage of shared CBPeripheralManager for GATT and L2CAP
|
||||
// servers.
|
||||
constexpr auto kEnableSharedPeripheralManager =
|
||||
flags::Flag<bool>(kConfigPackage, "45770787", false);
|
||||
// Set the safe-to-disconnect version.
|
||||
// 0. Disabled all. 1. safe-to-disconnect 2. reserved 3. auto-reconnect
|
||||
// 4. auto-resume 5. non-distance-constraint-recovery 6. payload_ack
|
||||
|
||||
@@ -29,4 +29,7 @@
|
||||
/** Checks whether BLE L2CAP refactor is enabled in the Nearby Connections SDK. */
|
||||
@property(nonatomic, class, readonly) BOOL refactorBleL2capEnabled;
|
||||
|
||||
/** Checks whether shared peripheral manager is enabled in the Nearby Connections SDK. */
|
||||
@property(nonatomic, class, readonly) BOOL sharedPeripheralManagerEnabled;
|
||||
|
||||
@end
|
||||
|
||||
@@ -42,4 +42,10 @@
|
||||
kRefactorBleL2cap);
|
||||
}
|
||||
|
||||
+ (BOOL)sharedPeripheralManagerEnabled {
|
||||
return nearby::NearbyFlags::GetInstance().GetBoolFlag(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -34,6 +34,13 @@
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::kEnableBleL2cap,
|
||||
false);
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::kRefactorBleL2cap,
|
||||
false);
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
false);
|
||||
|
||||
[super tearDown];
|
||||
}
|
||||
@@ -78,4 +85,34 @@
|
||||
XCTAssertFalse([GNCFeatureFlags bleL2capEnabled]);
|
||||
}
|
||||
|
||||
- (void)testRefactorBleL2capEnabled_WhenFlagIsTrue {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::kRefactorBleL2cap,
|
||||
YES);
|
||||
XCTAssertTrue([GNCFeatureFlags refactorBleL2capEnabled]);
|
||||
}
|
||||
|
||||
- (void)testRefactorBleL2capEnabled_WhenFlagIsFalse {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::kRefactorBleL2cap,
|
||||
NO);
|
||||
XCTAssertFalse([GNCFeatureFlags refactorBleL2capEnabled]);
|
||||
}
|
||||
|
||||
- (void)testSharedPeripheralManagerEnabled_WhenFlagIsTrue {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
YES);
|
||||
XCTAssertTrue([GNCFeatureFlags sharedPeripheralManagerEnabled]);
|
||||
}
|
||||
|
||||
- (void)testSharedPeripheralManagerEnabled_WhenFlagIsFalse {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
NO);
|
||||
XCTAssertFalse([GNCFeatureFlags sharedPeripheralManagerEnabled]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#import <CoreBluetooth/CoreBluetooth.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManager.h"
|
||||
|
||||
@class GNCBLEGATTCharacteristic;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@@ -57,7 +59,18 @@ typedef void (^GNCStopAdvertisingCompletionHandler)(NSError *_Nullable error);
|
||||
*
|
||||
* @note The public APIs of this class are thread safe.
|
||||
*/
|
||||
@interface GNCBLEGATTServer : NSObject
|
||||
@interface GNCBLEGATTServer : NSObject <GNCPeripheralManagerDelegate>
|
||||
|
||||
/**
|
||||
* Initializes the GATT server.
|
||||
*
|
||||
* @param peripheralManager The peripheral manager to use.
|
||||
* @param queue The queue to use for delegate callbacks and internal operations.
|
||||
*/
|
||||
- (instancetype)initWithPeripheralManager:(nullable id<GNCPeripheralManager>)peripheralManager
|
||||
queue:(nullable dispatch_queue_t)queue;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
* Creates a characteristic and adds it to the GATT server.
|
||||
|
||||
@@ -59,30 +59,33 @@ static const int kMaxAdvertisementLengthOnIOS = 23;
|
||||
NSDictionary<NSString *, id> *_advertisementData;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
- (instancetype)initWithPeripheralManager:(nullable id<GNCPeripheralManager>)peripheralManager
|
||||
queue:(nullable dispatch_queue_t)queue {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_queue = dispatch_queue_create(kGNCBLEGATTServerQueueLabel, DISPATCH_QUEUE_SERIAL);
|
||||
_peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:nil queue:_queue];
|
||||
// Set for @c GNCPeripheralManager to be able to forward callbacks.
|
||||
_peripheralManager.peripheralDelegate = self;
|
||||
_services = [[NSMutableDictionary alloc] init];
|
||||
_pendingCharacteristics = [[NSMutableDictionary alloc] init];
|
||||
_characteristicValues = [[NSMutableDictionary alloc] init];
|
||||
_advertisementData = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
_queue = queue ?: dispatch_queue_create(kGNCBLEGATTServerQueueLabel, DISPATCH_QUEUE_SERIAL);
|
||||
if (GNCFeatureFlags.sharedPeripheralManagerEnabled) {
|
||||
if (!peripheralManager) {
|
||||
// In shared mode, the peripheral manager must be injected.
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"Peripheral manager cannot be nil when shared manager is enabled."];
|
||||
}
|
||||
_peripheralManager = peripheralManager;
|
||||
// In shared mode, do NOT set the delegate. The Multiplexer handles callbacks.
|
||||
} else {
|
||||
// Legacy mode: Create a new manager if one isn't provided.
|
||||
if (!peripheralManager) {
|
||||
peripheralManager = [[CBPeripheralManager alloc]
|
||||
initWithDelegate:self
|
||||
queue:_queue
|
||||
options:@{CBPeripheralManagerOptionShowPowerAlertKey : @NO}];
|
||||
}
|
||||
_peripheralManager = peripheralManager;
|
||||
// In legacy mode, we own the manager (or use the injected one as if we own it) and set the
|
||||
// delegate.
|
||||
_peripheralManager.peripheralDelegate = self;
|
||||
}
|
||||
|
||||
// This is private and should only be used for tests. The provided peripheral manager must call
|
||||
// delegate methods on the main queue.
|
||||
- (instancetype)initWithPeripheralManager:(nullable id<GNCPeripheralManager>)peripheralManager {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_queue = dispatch_get_main_queue();
|
||||
_peripheralManager = peripheralManager;
|
||||
// Set for @c GNCPeripheralManager to be able to forward callbacks.
|
||||
_peripheralManager.peripheralDelegate = self;
|
||||
_services = [[NSMutableDictionary alloc] init];
|
||||
_pendingCharacteristics = [[NSMutableDictionary alloc] init];
|
||||
_characteristicValues = [[NSMutableDictionary alloc] init];
|
||||
@@ -342,6 +345,12 @@ static const int kMaxAdvertisementLengthOnIOS = 23;
|
||||
- (void)gnc_peripheralManager:(id<GNCPeripheralManager>)peripheral
|
||||
didReceiveReadRequest:(CBATTRequest *)request {
|
||||
dispatch_assert_queue(_queue);
|
||||
if (!_services[request.characteristic.service.UUID]) {
|
||||
// This server does not own the requested service. Ignore the request to allow other listeners
|
||||
// (or future listeners) to handle it.
|
||||
return;
|
||||
}
|
||||
|
||||
NSData *value =
|
||||
_characteristicValues[request.characteristic.service.UUID][request.characteristic.UUID];
|
||||
if (!value) {
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#import <CoreBluetooth/CoreBluetooth.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/GNCPeripheralManager.h"
|
||||
|
||||
@class GNCBLEL2CAPStream;
|
||||
@protocol GNCPeripheralManager;
|
||||
|
||||
@@ -42,7 +44,7 @@ typedef void (^GNCOpenL2CAPServerChannelOpendCompletionHandler)(GNCBLEL2CAPStrea
|
||||
*
|
||||
* @note The public APIs of this class are thread safe.
|
||||
*/
|
||||
@interface GNCBLEL2CAPServer : NSObject
|
||||
@interface GNCBLEL2CAPServer : NSObject <GNCPeripheralManagerDelegate>
|
||||
|
||||
// Represents a PSM (Protocol/Service Multiplexer) value for an L2CAP channel.
|
||||
@property(atomic, readonly) CBL2CAPPSM PSM;
|
||||
@@ -57,6 +59,8 @@ typedef void (^GNCOpenL2CAPServerChannelOpendCompletionHandler)(GNCBLEL2CAPStrea
|
||||
- (instancetype)initWithPeripheralManager:(nullable id<GNCPeripheralManager>)peripheralManager
|
||||
queue:(nullable dispatch_queue_t)queue;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
* Starts listening for an L2CAP channel.
|
||||
*
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#import <CoreBluetooth/CoreBluetooth.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "internal/platform/implementation/apple/Flags/GNCFeatureFlags.h"
|
||||
#import "internal/platform/implementation/apple/Log/GNCLogger.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEError.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPStream.h"
|
||||
@@ -43,21 +44,25 @@ static char *const kGNCBLEL2CAPServerQueueLabel = "com.google.nearby.GNCBLEL2CAP
|
||||
BOOL _alreadyStartedWhenPeripheralPoweredOff;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
return [self initWithPeripheralManager:nil queue:nil];
|
||||
}
|
||||
|
||||
// This is private and should only be used for tests. The provided peripheral manager must call
|
||||
// delegate methods on the main queue.
|
||||
- (instancetype)initWithPeripheralManager:(nullable id<GNCPeripheralManager>)peripheralManager
|
||||
queue:(nullable dispatch_queue_t)queue {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_queue = queue ?: dispatch_queue_create(kGNCBLEL2CAPServerQueueLabel, DISPATCH_QUEUE_SERIAL);
|
||||
if (peripheralManager) {
|
||||
if (GNCFeatureFlags.sharedPeripheralManagerEnabled) {
|
||||
if (!peripheralManager) {
|
||||
// In shared mode, the peripheral manager must be injected.
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"Peripheral manager cannot be nil when shared manager is enabled."];
|
||||
}
|
||||
_peripheralManager = peripheralManager;
|
||||
// Set for @c GNCPeripheralManager to be able to forward callbacks.
|
||||
_peripheralManager.peripheralDelegate = self;
|
||||
// In shared mode, do NOT set the delegate. The Multiplexer handles callbacks.
|
||||
} else {
|
||||
if (peripheralManager) {
|
||||
_peripheralManager = peripheralManager;
|
||||
// Set for @c GNCPeripheralManager to be able to forward callbacks.
|
||||
_peripheralManager.peripheralDelegate = self;
|
||||
}
|
||||
}
|
||||
}
|
||||
return self;
|
||||
@@ -70,20 +75,36 @@ static char *const kGNCBLEL2CAPServerQueueLabel = "com.google.nearby.GNCBLEL2CAP
|
||||
channelOpenedCompletionHandler {
|
||||
_psmPublishedCompletionHandler = [psmPublishedCompletionHandler copy];
|
||||
_channelOpenedCompletionHandler = [channelOpenedCompletionHandler copy];
|
||||
if (!_queue) {
|
||||
_psmPublishedCompletionHandler(0, [NSError errorWithDomain:GNCBLEErrorDomain
|
||||
code:GNCBLEErrorL2CAPListeningOnQueueNil
|
||||
userInfo:nil]);
|
||||
return;
|
||||
}
|
||||
if (!_peripheralManager) {
|
||||
// Lazy initialization to avoid system dialog on app startup before pairing.
|
||||
_peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:nil
|
||||
queue:_queue
|
||||
options:nil];
|
||||
if (GNCFeatureFlags.sharedPeripheralManagerEnabled) {
|
||||
if (!_queue) {
|
||||
if (_psmPublishedCompletionHandler) {
|
||||
_psmPublishedCompletionHandler(0,
|
||||
[NSError errorWithDomain:GNCBLEErrorDomain
|
||||
code:GNCBLEErrorL2CAPListeningOnQueueNil
|
||||
userInfo:nil]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!_peripheralManager) {
|
||||
GNCLoggerError(@"[NEARBY] Peripheral manager must not be nil.");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!_queue) {
|
||||
_psmPublishedCompletionHandler(0, [NSError errorWithDomain:GNCBLEErrorDomain
|
||||
code:GNCBLEErrorL2CAPListeningOnQueueNil
|
||||
userInfo:nil]);
|
||||
return;
|
||||
}
|
||||
if (!_peripheralManager) {
|
||||
// Lazy initialization to avoid system dialog on app startup before pairing.
|
||||
_peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:nil
|
||||
queue:_queue
|
||||
options:nil];
|
||||
|
||||
// Set for @c GNCPeripheralManager to be able to forward callbacks.
|
||||
_peripheralManager.peripheralDelegate = self;
|
||||
// Set for @c GNCPeripheralManager to be able to forward callbacks.
|
||||
_peripheralManager.peripheralDelegate = self;
|
||||
}
|
||||
}
|
||||
|
||||
if (_peripheralManager.state == CBManagerStatePoweredOn) {
|
||||
|
||||
@@ -40,16 +40,6 @@ static NSError *AlreadyScanningError() {
|
||||
return [NSError errorWithDomain:GNCBLEErrorDomain code:GNCBLEErrorAlreadyScanning userInfo:nil];
|
||||
}
|
||||
|
||||
static GNCBLEL2CAPServer *_Nonnull CreateL2CapServer(
|
||||
id<GNCPeripheralManager> _Nullable peripheralManager) {
|
||||
if (!peripheralManager) {
|
||||
return [[GNCBLEL2CAPServer alloc] init];
|
||||
} else {
|
||||
return [[GNCBLEL2CAPServer alloc] initWithPeripheralManager:peripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
}
|
||||
}
|
||||
|
||||
@interface GNCBLEMedium () <GNCCentralManagerDelegate, CBCentralManagerDelegate>
|
||||
@end
|
||||
|
||||
@@ -164,7 +154,16 @@ static GNCBLEL2CAPServer *_Nonnull CreateL2CapServer(
|
||||
completionHandler:(nullable GNCStartAdvertisingCompletionHandler)completionHandler {
|
||||
dispatch_async(_queue, ^{
|
||||
if (!_server) {
|
||||
_server = [[GNCBLEGATTServer alloc] init];
|
||||
if (GNCFeatureFlags.sharedPeripheralManagerEnabled) {
|
||||
// TODO (edwinwu): Implement shared peripheral manager.
|
||||
// For now, raise an exception.
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"Not implemented for shared manager is enabled."];
|
||||
} else {
|
||||
// In legacy mode, we pass nil (or a separate manager) and do NOT add to multiplexer.
|
||||
// GNCBLEGATTServer will create its own internal manager.
|
||||
_server = [[GNCBLEGATTServer alloc] initWithPeripheralManager:nil queue:nil];
|
||||
}
|
||||
}
|
||||
[_server startAdvertisingData:serviceData completionHandler:completionHandler];
|
||||
});
|
||||
@@ -238,7 +237,14 @@ static GNCBLEL2CAPServer *_Nonnull CreateL2CapServer(
|
||||
(nullable GNCGATTServerCompletionHandler)completionHandler {
|
||||
dispatch_async(_queue, ^{
|
||||
if (!_server) {
|
||||
_server = [[GNCBLEGATTServer alloc] init];
|
||||
if (GNCFeatureFlags.sharedPeripheralManagerEnabled) {
|
||||
// TODO (edwinwu): Implement shared peripheral manager.
|
||||
// For now, raise an exception.
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"Not implemented for shared manager is enabled."];
|
||||
} else {
|
||||
_server = [[GNCBLEGATTServer alloc] initWithPeripheralManager:nil queue:nil];
|
||||
}
|
||||
}
|
||||
if (completionHandler) {
|
||||
completionHandler(_server, nil);
|
||||
@@ -284,7 +290,17 @@ static GNCBLEL2CAPServer *_Nonnull CreateL2CapServer(
|
||||
(nullable id<GNCPeripheralManager>)peripheralManager {
|
||||
dispatch_async(_queue, ^{
|
||||
if (!_l2capServer) {
|
||||
_l2capServer = CreateL2CapServer(peripheralManager);
|
||||
if (GNCFeatureFlags.sharedPeripheralManagerEnabled) {
|
||||
// TODO (edwinwu): Implement shared peripheral manager.
|
||||
// For now, raise an exception.
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"Not implemented for shared manager is enabled."];
|
||||
} else {
|
||||
// Legacy mode
|
||||
_l2capServer = [[GNCBLEL2CAPServer alloc]
|
||||
initWithPeripheralManager:peripheralManager // Likely nil, so Server creates new one
|
||||
queue:peripheralManager ? dispatch_get_main_queue() : nil];
|
||||
}
|
||||
}
|
||||
[_l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:psmPublishedCompletionHandler
|
||||
|
||||
@@ -26,11 +26,11 @@ objc_library(
|
||||
srcs = [
|
||||
"GNCBLEGATTCharacteristicTest.mm",
|
||||
"GNCBLEGATTClientTest.m",
|
||||
"GNCBLEGATTServerTest.m",
|
||||
"GNCBLEGATTServerTest.mm",
|
||||
"GNCBLEL2CAPClientTest.m",
|
||||
"GNCBLEL2CAPConnectionTest.m",
|
||||
"GNCBLEL2CAPFakeInputOutputStream.m",
|
||||
"GNCBLEL2CAPServerTest.m",
|
||||
"GNCBLEL2CAPServerTest.mm",
|
||||
"GNCBLEL2CAPStreamTest.m",
|
||||
"GNCBLEMediumTest.m",
|
||||
"GNCFakeBLEGATTServer.m",
|
||||
@@ -66,6 +66,8 @@ objc_library(
|
||||
"GNCMFakeConnection.h",
|
||||
],
|
||||
deps = [
|
||||
"//connections/implementation/flags:connections_flags",
|
||||
"//internal/flags:nearby_flags",
|
||||
"//internal/platform/implementation/apple", # buildcleaner: keep
|
||||
"//internal/platform/implementation/apple/Mediums/BLE",
|
||||
"//internal/platform/implementation/apple/Mediums/BLE/Sockets:Shared",
|
||||
|
||||
+362
-104
@@ -22,6 +22,9 @@
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEGATTServer+Testing.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.h"
|
||||
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
|
||||
static NSString *const kServiceUUID1 = @"0000FEF3-0000-1000-8000-00805F9B34FB";
|
||||
static NSString *const kServiceUUID2 = @"0000FEF4-0000-1000-8000-00805F9B34FB";
|
||||
static NSString *const kCharacteristicUUID1 = @"00000000-0000-3000-8000-000000000000";
|
||||
@@ -34,11 +37,60 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
|
||||
#pragma mark - Create Characteristic
|
||||
|
||||
- (void)testCreateCharacteristic {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
- (void)tearDown {
|
||||
nearby::NearbyFlags::GetInstance().ResetOverridedValues();
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
- (void)testInit_setsDelegateCorrectlyBasedOnFlag {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEGATTServer *server =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
|
||||
if (enabled.boolValue) {
|
||||
// In shared mode, functionality is delegated to the multiplexer, so the server should NOT
|
||||
// self-assign as delegate.
|
||||
XCTAssertNil(fakePeripheralManager.peripheralDelegate);
|
||||
} else {
|
||||
// In legacy mode, the server owns the manager and sets itself as delegate.
|
||||
XCTAssertEqual(fakePeripheralManager.peripheralDelegate, server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testInit_throwsWithNilManagerWhenFlagEnabled {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
true);
|
||||
|
||||
XCTAssertThrowsSpecificNamed(
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:(id<GNCPeripheralManager>)nil
|
||||
queue:dispatch_get_main_queue()],
|
||||
NSException, NSInvalidArgumentException);
|
||||
}
|
||||
|
||||
- (void)testCreateCharacteristic {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
@@ -62,13 +114,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testCreateMultipleCharacteristicsForOneService {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
@@ -105,13 +167,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
[self waitForExpectations:@[ expectation1, expectation2 ] timeout:3];
|
||||
XCTAssertEqual(fakePeripheralManager.services.count, 1);
|
||||
XCTAssertEqual(fakePeripheralManager.services[0].characteristics.count, 2);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testCreateDuplicateCharacteristics {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
@@ -140,13 +212,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
XCTAssertEqual(fakePeripheralManager.services.count, 1);
|
||||
XCTAssertEqual(fakePeripheralManager.services[0].characteristics.count, 1);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testCreateDuplicatePendingCharacteristics {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
XCTestExpectation *expectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"Create characteristic."];
|
||||
@@ -171,13 +253,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testCreateCharacteristicNotPoweredOn {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
XCTestExpectation *expectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"Create characteristic."];
|
||||
@@ -198,13 +290,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testCreateCharacteristicServiceFailure {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
fakePeripheralManager.didAddServiceError = [NSError errorWithDomain:@"fake" code:0 userInfo:nil];
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
@@ -228,15 +330,25 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Read Request
|
||||
|
||||
- (void)testReadRequest {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
@@ -265,14 +377,24 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
characteristic:characteristicUUID];
|
||||
|
||||
[self waitForExpectations:@[ fakePeripheralManager.respondToRequestSuccessExpectation ]
|
||||
timeout:0];
|
||||
timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testReadRequestInvalidService {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
- (void)testReadRequestInvalidCharacteristic {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
@@ -296,73 +418,106 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
|
||||
CBUUID *invalidCharacteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID2];
|
||||
|
||||
[fakePeripheralManager
|
||||
simulatePeripheralManagerDidReceiveReadRequestForService:serviceUUID
|
||||
characteristic:invalidCharacteristicUUID];
|
||||
|
||||
[self waitForExpectations:@[ fakePeripheralManager.respondToRequestErrorExpectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testReadRequestInvalidService {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
XCTestExpectation *expectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"Create characteristic."];
|
||||
|
||||
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
|
||||
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
|
||||
[gattServer createCharacteristicWithServiceID:serviceUUID
|
||||
characteristicUUID:characteristicUUID
|
||||
permissions:CBAttributePermissionsReadable
|
||||
properties:CBCharacteristicPropertyRead
|
||||
completionHandler:^(GNCBLEGATTCharacteristic *characteristic,
|
||||
NSError *error) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
|
||||
CBUUID *invalidServiceUUID = [CBUUID UUIDWithString:kServiceUUID2];
|
||||
|
||||
// Expectation that we *should not* receive a response.
|
||||
fakePeripheralManager.respondToRequestSuccessExpectation.inverted = YES;
|
||||
fakePeripheralManager.respondToRequestErrorExpectation.inverted = YES;
|
||||
|
||||
[fakePeripheralManager
|
||||
simulatePeripheralManagerDidReceiveReadRequestForService:invalidServiceUUID
|
||||
characteristic:characteristicUUID];
|
||||
|
||||
[self waitForExpectations:@[ fakePeripheralManager.respondToRequestErrorExpectation ] timeout:0];
|
||||
}
|
||||
|
||||
- (void)testReadRequestInvalidCharacteristic {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
XCTestExpectation *expectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"Create and update characteristic."];
|
||||
|
||||
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
|
||||
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
|
||||
[gattServer createCharacteristicWithServiceID:serviceUUID
|
||||
characteristicUUID:characteristicUUID
|
||||
permissions:CBAttributePermissionsReadable
|
||||
properties:CBCharacteristicPropertyRead
|
||||
completionHandler:^(GNCBLEGATTCharacteristic *characteristic,
|
||||
NSError *error) {
|
||||
[gattServer updateCharacteristic:characteristic
|
||||
value:[NSData data]
|
||||
completionHandler:^(NSError *error) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
|
||||
CBUUID *invalidCharacteristicUUID =
|
||||
[CBUUID UUIDWithString:kCharacteristicUUID2];
|
||||
|
||||
[fakePeripheralManager
|
||||
simulatePeripheralManagerDidReceiveReadRequestForService:serviceUUID
|
||||
characteristic:invalidCharacteristicUUID];
|
||||
|
||||
[self waitForExpectations:@[ fakePeripheralManager.respondToRequestErrorExpectation ] timeout:0];
|
||||
[self waitForExpectations:@[
|
||||
fakePeripheralManager.respondToRequestSuccessExpectation,
|
||||
fakePeripheralManager.respondToRequestErrorExpectation
|
||||
]
|
||||
timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Stop
|
||||
|
||||
- (void)testStop {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[gattServer stop];
|
||||
[gattServer stop];
|
||||
|
||||
XCTAssertEqual(fakePeripheralManager.services.count, 0);
|
||||
XCTAssertEqual(fakePeripheralManager.services.count, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Start Advertising
|
||||
|
||||
- (void)testStartAdvertisingNoServiceData {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
@@ -377,13 +532,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testStartAdvertisingEmptyServiceData {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
@@ -402,13 +567,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testStartAdvertisingShortServiceData {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
@@ -429,13 +604,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testStartAdvertising20ByteServiceData {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
@@ -457,13 +642,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testStartAdvertisingLongServiceData {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
@@ -482,13 +677,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testStartAdvertisingWithEmojiServiceData {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
@@ -510,13 +715,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testStartAdvertisingMultipleServices {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
@@ -536,13 +751,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testStartAdvertisingNotPoweredOn {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
XCTestExpectation *expectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"Start advertising."];
|
||||
@@ -556,13 +781,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testStartAdvertisingStartFailure {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
fakePeripheralManager.didStartAdvertisingError = [NSError errorWithDomain:@"fake"
|
||||
code:0
|
||||
@@ -581,13 +816,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testStartAdvertisingAlreadyAdvertising {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
fakePeripheralManager.didStartAdvertisingError = [NSError errorWithDomain:@"fake"
|
||||
code:0
|
||||
@@ -608,13 +853,23 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testStartStopStartAdvertising {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager];
|
||||
GNCBLEGATTServer *gattServer =
|
||||
[[GNCBLEGATTServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = gattServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
@@ -648,6 +903,9 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
|
||||
}];
|
||||
|
||||
[self waitForExpectations:@[ expectation ] timeout:3];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -1,329 +0,0 @@
|
||||
// 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.
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.h"
|
||||
|
||||
#import <CoreBluetooth/CoreBluetooth.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPServer+Testing.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.h"
|
||||
|
||||
static const NSTimeInterval kTestTimeout = 1.0;
|
||||
|
||||
@interface GNCBLEL2CAPServerTest : XCTestCase
|
||||
@end
|
||||
|
||||
@implementation GNCBLEL2CAPServerTest
|
||||
|
||||
#pragma mark Tests
|
||||
|
||||
- (void)testInit {
|
||||
GNCBLEL2CAPServer *l2capServer = [[GNCBLEL2CAPServer alloc] init];
|
||||
XCTAssertNotNil(l2capServer);
|
||||
XCTAssertNil([l2capServer valueForKey:@"_peripheralManager"]);
|
||||
}
|
||||
|
||||
- (void)testPublishL2CAPChannelAndOpenChannelWhenStartListeningChannel {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
XCTestExpectation *psmPublishedExpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"PSM published."];
|
||||
XCTestExpectation *channelOpenedexpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"Channel opened."];
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, nil);
|
||||
XCTAssertEqual(PSM, fakePeripheralManager.PSM);
|
||||
[psmPublishedExpectation fulfill];
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertNil(error);
|
||||
XCTAssertNotNil(stream);
|
||||
[channelOpenedexpectation fulfill];
|
||||
}];
|
||||
[self waitForExpectations:@[ psmPublishedExpectation, channelOpenedexpectation ]
|
||||
timeout:kTestTimeout];
|
||||
XCTAssertNotNil([l2capServer valueForKey:@"l2CAPChannel"]);
|
||||
XCTAssertNotNil([l2capServer valueForKey:@"l2CAPStream"]);
|
||||
}
|
||||
|
||||
- (void)testFailedToPublishL2CAPChannel {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
fakePeripheralManager.didPublishL2CAPChannelError = [NSError errorWithDomain:@"fake"
|
||||
code:0
|
||||
userInfo:nil];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
XCTestExpectation *psmPublishedExpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"PSM published with error."];
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, fakePeripheralManager.didPublishL2CAPChannelError);
|
||||
XCTAssertEqual(PSM, 0);
|
||||
[psmPublishedExpectation fulfill];
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
[self waitForExpectations:@[ psmPublishedExpectation ] timeout:kTestTimeout];
|
||||
}
|
||||
|
||||
- (void)testPoweredOffUnpublishesChannel {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, nil);
|
||||
XCTAssertEqual(PSM, fakePeripheralManager.PSM);
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOff];
|
||||
|
||||
[self waitForExpectations:@[ fakePeripheralManager.unpublishExpectation ] timeout:kTestTimeout];
|
||||
}
|
||||
|
||||
- (void)testPeripheralManagerDidUpdateStatePoweredOffUnpublishesChannel {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
fakePeripheralManager.state = CBManagerStatePoweredOn;
|
||||
[(id<CBPeripheralManagerDelegate>)l2capServer
|
||||
peripheralManagerDidUpdateState:(CBPeripheralManager *)fakePeripheralManager];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, nil);
|
||||
XCTAssertEqual(PSM, fakePeripheralManager.PSM);
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
|
||||
fakePeripheralManager.state = CBManagerStatePoweredOff;
|
||||
[(id<CBPeripheralManagerDelegate>)l2capServer
|
||||
peripheralManagerDidUpdateState:(CBPeripheralManager *)fakePeripheralManager];
|
||||
|
||||
[self waitForExpectations:@[ fakePeripheralManager.unpublishExpectation ] timeout:kTestTimeout];
|
||||
}
|
||||
|
||||
- (void)testStartPeripheralManagerInitiallyOff {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
XCTestExpectation *psmPublishedExpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"PSM published."];
|
||||
XCTestExpectation *channelOpenedexpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"Channel opened."];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, nil);
|
||||
XCTAssertEqual(PSM, fakePeripheralManager.PSM);
|
||||
[psmPublishedExpectation fulfill];
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error) {
|
||||
[channelOpenedexpectation fulfill];
|
||||
}];
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
[self waitForExpectations:@[ psmPublishedExpectation, channelOpenedexpectation ]
|
||||
timeout:kTestTimeout];
|
||||
}
|
||||
|
||||
- (void)testClose {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, nil);
|
||||
XCTAssertEqual(PSM, fakePeripheralManager.PSM);
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
|
||||
[l2capServer close];
|
||||
|
||||
XCTAssertEqual([l2capServer PSM], 0);
|
||||
}
|
||||
|
||||
- (void)testCloseDoesNotUnpublishesChannelIfNotConnected {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
fakePeripheralManager.unpublishExpectation.inverted = YES;
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
|
||||
[l2capServer close];
|
||||
|
||||
[self waitForExpectations:@[ fakePeripheralManager.unpublishExpectation ] timeout:kTestTimeout];
|
||||
}
|
||||
|
||||
- (void)testFailedToOpenL2CAPChannel {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
fakePeripheralManager.didOpenL2CAPChannelError = [NSError errorWithDomain:@"fake"
|
||||
code:0
|
||||
userInfo:nil];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
XCTestExpectation *channelOpenedexpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"Channel opened."];
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, nil);
|
||||
XCTAssertEqual(PSM, fakePeripheralManager.PSM);
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertNil(stream);
|
||||
XCTAssertEqual(error, fakePeripheralManager.didOpenL2CAPChannelError);
|
||||
[channelOpenedexpectation fulfill];
|
||||
}];
|
||||
[self waitForExpectations:@[ channelOpenedexpectation ] timeout:kTestTimeout];
|
||||
XCTAssertNil([l2capServer valueForKey:@"l2CAPChannel"]);
|
||||
XCTAssertNil([l2capServer valueForKey:@"l2CAPStream"]);
|
||||
}
|
||||
|
||||
- (void)testPeripheralManagerDidUnpublishL2CAPChannel {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
|
||||
[(id<CBPeripheralManagerDelegate>)l2capServer
|
||||
peripheralManager:(CBPeripheralManager *)fakePeripheralManager
|
||||
didUnpublishL2CAPChannel:l2capServer.PSM
|
||||
error:[NSError errorWithDomain:@"fake" code:0 userInfo:nil]];
|
||||
|
||||
XCTAssertEqual(l2capServer.PSM, 0);
|
||||
}
|
||||
|
||||
- (void)testCloseL2CAPChannel {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
XCTestExpectation *channelOpenedexpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"Channel opened."];
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error) {
|
||||
[channelOpenedexpectation fulfill];
|
||||
}];
|
||||
[self waitForExpectations:@[ channelOpenedexpectation ] timeout:kTestTimeout];
|
||||
|
||||
[l2capServer closeL2CAPChannel];
|
||||
|
||||
XCTAssertNil([l2capServer valueForKey:@"l2CAPChannel"]);
|
||||
XCTAssertNil([l2capServer valueForKey:@"l2CAPStream"]);
|
||||
}
|
||||
|
||||
- (void)testPeripheralManagerDidPublishL2CAPChannel {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
XCTestExpectation *expectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"completion called"];
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(PSM, 1);
|
||||
XCTAssertNil(error);
|
||||
[expectation fulfill];
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
[(id<CBPeripheralManagerDelegate>)l2capServer
|
||||
peripheralManager:(CBPeripheralManager *)fakePeripheralManager
|
||||
didPublishL2CAPChannel:1
|
||||
error:nil];
|
||||
[self waitForExpectations:@[ expectation ] timeout:kTestTimeout];
|
||||
XCTAssertEqual(l2capServer.PSM, 1);
|
||||
}
|
||||
|
||||
- (void)testPeripheralManagerDidPublishL2CAPChannelWithError {
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
XCTestExpectation *expectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"completion called"];
|
||||
NSError *publishError = [NSError errorWithDomain:@"test" code:0 userInfo:nil];
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(PSM, 0);
|
||||
XCTAssertEqualObjects(error, publishError);
|
||||
[expectation fulfill];
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
[(id<CBPeripheralManagerDelegate>)l2capServer
|
||||
peripheralManager:(CBPeripheralManager *)fakePeripheralManager
|
||||
didPublishL2CAPChannel:0
|
||||
error:publishError];
|
||||
[self waitForExpectations:@[ expectation ] timeout:kTestTimeout];
|
||||
XCTAssertEqual(l2capServer.PSM, 0);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,485 @@
|
||||
// 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.
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/GNCBLEL2CAPServer.h"
|
||||
|
||||
#import <CoreBluetooth/CoreBluetooth.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCBLEL2CAPServer+Testing.h"
|
||||
#import "internal/platform/implementation/apple/Mediums/BLE/Tests/GNCFakePeripheralManager.h"
|
||||
|
||||
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
|
||||
#include "internal/flags/nearby_flags.h"
|
||||
|
||||
static const NSTimeInterval kTestTimeout = 1.0;
|
||||
|
||||
@interface GNCBLEL2CAPServerTest : XCTestCase
|
||||
@end
|
||||
|
||||
@implementation GNCBLEL2CAPServerTest
|
||||
|
||||
#pragma mark Tests
|
||||
|
||||
- (void)tearDown {
|
||||
nearby::NearbyFlags::GetInstance().ResetOverridedValues();
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testInit_setsDelegateCorrectlyBasedOnFlag {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *server =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
|
||||
if (enabled.boolValue) {
|
||||
// In shared mode, functionality is delegated to the multiplexer, so the server should NOT
|
||||
// self-assign as delegate.
|
||||
XCTAssertNil(fakePeripheralManager.peripheralDelegate);
|
||||
} else {
|
||||
// In legacy mode, the server owns the manager and sets itself as delegate.
|
||||
XCTAssertEqual(fakePeripheralManager.peripheralDelegate, server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testInit_throwsWithNilManagerWhenFlagEnabled {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
true);
|
||||
|
||||
XCTAssertThrowsSpecificNamed(
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:(id<GNCPeripheralManager>)nil
|
||||
queue:dispatch_get_main_queue()],
|
||||
NSException, NSInvalidArgumentException);
|
||||
}
|
||||
|
||||
- (void)testPublishL2CAPChannelAndOpenChannelWhenStartListeningChannel {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = l2capServer;
|
||||
}
|
||||
|
||||
XCTestExpectation *psmPublishedExpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"PSM published."];
|
||||
XCTestExpectation *channelOpenedexpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"Channel opened."];
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, nil);
|
||||
XCTAssertEqual(PSM, fakePeripheralManager.PSM);
|
||||
[psmPublishedExpectation fulfill];
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertNil(error);
|
||||
XCTAssertNotNil(stream);
|
||||
[channelOpenedexpectation fulfill];
|
||||
}];
|
||||
[self waitForExpectations:@[ psmPublishedExpectation, channelOpenedexpectation ]
|
||||
timeout:kTestTimeout];
|
||||
XCTAssertNotNil([l2capServer valueForKey:@"l2CAPChannel"]);
|
||||
XCTAssertNotNil([l2capServer valueForKey:@"l2CAPStream"]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testFailedToPublishL2CAPChannel {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
fakePeripheralManager.didPublishL2CAPChannelError = [NSError errorWithDomain:@"fake"
|
||||
code:0
|
||||
userInfo:nil];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = l2capServer;
|
||||
}
|
||||
|
||||
XCTestExpectation *psmPublishedExpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"PSM published with error."];
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, fakePeripheralManager.didPublishL2CAPChannelError);
|
||||
XCTAssertEqual(PSM, 0);
|
||||
[psmPublishedExpectation fulfill];
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
[self waitForExpectations:@[ psmPublishedExpectation ] timeout:kTestTimeout];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testPoweredOffUnpublishesChannel {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = l2capServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, nil);
|
||||
XCTAssertEqual(PSM, fakePeripheralManager.PSM);
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOff];
|
||||
|
||||
[self waitForExpectations:@[ fakePeripheralManager.unpublishExpectation ] timeout:kTestTimeout];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testPeripheralManagerDidUpdateStatePoweredOffUnpublishesChannel {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = l2capServer;
|
||||
}
|
||||
fakePeripheralManager.state = CBManagerStatePoweredOn;
|
||||
[(id<CBPeripheralManagerDelegate>)l2capServer
|
||||
peripheralManagerDidUpdateState:(CBPeripheralManager *)fakePeripheralManager];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, nil);
|
||||
XCTAssertEqual(PSM, fakePeripheralManager.PSM);
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
|
||||
fakePeripheralManager.state = CBManagerStatePoweredOff;
|
||||
[(id<CBPeripheralManagerDelegate>)l2capServer
|
||||
peripheralManagerDidUpdateState:(CBPeripheralManager *)fakePeripheralManager];
|
||||
|
||||
[self waitForExpectations:@[ fakePeripheralManager.unpublishExpectation ] timeout:kTestTimeout];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testStartPeripheralManagerInitiallyOff {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = l2capServer;
|
||||
}
|
||||
|
||||
XCTestExpectation *psmPublishedExpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"PSM published."];
|
||||
XCTestExpectation *channelOpenedexpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"Channel opened."];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, nil);
|
||||
XCTAssertEqual(PSM, fakePeripheralManager.PSM);
|
||||
[psmPublishedExpectation fulfill];
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error) {
|
||||
[channelOpenedexpectation fulfill];
|
||||
}];
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
[self waitForExpectations:@[ psmPublishedExpectation, channelOpenedexpectation ]
|
||||
timeout:kTestTimeout];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testClose {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = l2capServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, nil);
|
||||
XCTAssertEqual(PSM, fakePeripheralManager.PSM);
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
|
||||
[l2capServer close];
|
||||
|
||||
XCTAssertEqual([l2capServer PSM], 0);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testCloseDoesNotUnpublishesChannelIfNotConnected {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
fakePeripheralManager.unpublishExpectation.inverted = YES;
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = l2capServer;
|
||||
}
|
||||
|
||||
[l2capServer close];
|
||||
|
||||
[self waitForExpectations:@[ fakePeripheralManager.unpublishExpectation ] timeout:kTestTimeout];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testFailedToOpenL2CAPChannel {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
fakePeripheralManager.didOpenL2CAPChannelError = [NSError errorWithDomain:@"fake"
|
||||
code:0
|
||||
userInfo:nil];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = l2capServer;
|
||||
}
|
||||
|
||||
XCTestExpectation *channelOpenedexpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"Channel opened."];
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(error, nil);
|
||||
XCTAssertEqual(PSM, fakePeripheralManager.PSM);
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertNil(stream);
|
||||
XCTAssertEqual(error, fakePeripheralManager.didOpenL2CAPChannelError);
|
||||
[channelOpenedexpectation fulfill];
|
||||
}];
|
||||
[self waitForExpectations:@[ channelOpenedexpectation ] timeout:kTestTimeout];
|
||||
XCTAssertNil([l2capServer valueForKey:@"l2CAPChannel"]);
|
||||
XCTAssertNil([l2capServer valueForKey:@"l2CAPStream"]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testPeripheralManagerDidUnpublishL2CAPChannel {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = l2capServer;
|
||||
}
|
||||
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
|
||||
[(id<CBPeripheralManagerDelegate>)l2capServer
|
||||
peripheralManager:(CBPeripheralManager *)fakePeripheralManager
|
||||
didUnpublishL2CAPChannel:l2capServer.PSM
|
||||
error:[NSError errorWithDomain:@"fake" code:0 userInfo:nil]];
|
||||
|
||||
XCTAssertEqual(l2capServer.PSM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testCloseL2CAPChannel {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = l2capServer;
|
||||
}
|
||||
|
||||
XCTestExpectation *channelOpenedexpectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"Channel opened."];
|
||||
[fakePeripheralManager simulatePeripheralManagerDidUpdateState:CBManagerStatePoweredOn];
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error) {
|
||||
[channelOpenedexpectation fulfill];
|
||||
}];
|
||||
[self waitForExpectations:@[ channelOpenedexpectation ] timeout:kTestTimeout];
|
||||
|
||||
[l2capServer closeL2CAPChannel];
|
||||
|
||||
XCTAssertNil([l2capServer valueForKey:@"l2CAPChannel"]);
|
||||
XCTAssertNil([l2capServer valueForKey:@"l2CAPStream"]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testPeripheralManagerDidPublishL2CAPChannel {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = l2capServer;
|
||||
}
|
||||
|
||||
XCTestExpectation *expectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"completion called"];
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(PSM, 1);
|
||||
XCTAssertNil(error);
|
||||
[expectation fulfill];
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
[(id<CBPeripheralManagerDelegate>)l2capServer
|
||||
peripheralManager:(CBPeripheralManager *)fakePeripheralManager
|
||||
didPublishL2CAPChannel:1
|
||||
error:nil];
|
||||
[self waitForExpectations:@[ expectation ] timeout:kTestTimeout];
|
||||
XCTAssertEqual(l2capServer.PSM, 1);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testPeripheralManagerDidPublishL2CAPChannelWithError {
|
||||
for (NSNumber *enabled in @[ @NO, @YES ]) {
|
||||
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
|
||||
nearby::connections::config_package_nearby::nearby_connections_feature::
|
||||
kEnableSharedPeripheralManager,
|
||||
enabled.boolValue);
|
||||
GNCFakePeripheralManager *fakePeripheralManager = [[GNCFakePeripheralManager alloc] init];
|
||||
GNCBLEL2CAPServer *l2capServer =
|
||||
[[GNCBLEL2CAPServer alloc] initWithPeripheralManager:fakePeripheralManager
|
||||
queue:dispatch_get_main_queue()];
|
||||
if (enabled.boolValue) {
|
||||
fakePeripheralManager.peripheralDelegate = l2capServer;
|
||||
}
|
||||
|
||||
XCTestExpectation *expectation =
|
||||
[[XCTestExpectation alloc] initWithDescription:@"completion called"];
|
||||
NSError *publishError = [NSError errorWithDomain:@"test" code:0 userInfo:nil];
|
||||
[l2capServer
|
||||
startListeningChannelWithPSMPublishedCompletionHandler:^(uint16_t PSM,
|
||||
NSError *_Nullable error) {
|
||||
XCTAssertEqual(PSM, 0);
|
||||
XCTAssertEqualObjects(error, publishError);
|
||||
[expectation fulfill];
|
||||
}
|
||||
channelOpenedCompletionHandler:^(GNCBLEL2CAPStream *_Nullable stream,
|
||||
NSError *_Nullable error){
|
||||
}];
|
||||
[(id<CBPeripheralManagerDelegate>)l2capServer
|
||||
peripheralManager:(CBPeripheralManager *)fakePeripheralManager
|
||||
didPublishL2CAPChannel:0
|
||||
error:publishError];
|
||||
[self waitForExpectations:@[ expectation ] timeout:kTestTimeout];
|
||||
XCTAssertEqual(l2capServer.PSM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -225,8 +225,8 @@ static const char *const kTestServiceID = "TestServiceID";
|
||||
#pragma mark - GATT Server Tests
|
||||
|
||||
- (void)testStartGattServer_Success {
|
||||
_fakeGNCBLEMedium.fakeGATTServer = [[GNCFakeBLEGATTServer alloc] init];
|
||||
|
||||
_fakeGNCBLEMedium.fakeGATTServer =
|
||||
[[GNCFakeBLEGATTServer alloc] initWithPeripheralManager:nil queue:nil];
|
||||
auto gatt_server = _medium->StartGattServer({});
|
||||
|
||||
XCTAssertNotEqual(gatt_server.get(), nullptr);
|
||||
|
||||
Reference in New Issue
Block a user