Update the logic to retrieve BLE peripheral.

PiperOrigin-RevId: 834816089
This commit is contained in:
Guogang Li
2025-11-20 10:27:57 -08:00
committed by Copybara-Service
parent ea2a651911
commit 919d279695
9 changed files with 88 additions and 5 deletions
@@ -243,6 +243,14 @@ typedef void (^GNCGATTConnectionCompletionHandler)(GNCBLEGATTClient *_Nullable c
*/
- (void)stop;
/**
* Retrieves the peripheral with the specified identifier.
*
* @param identifier The identifier of the peripheral to retrieve.
* @return The peripheral with the specified identifier, or @c nil if not found.
*/
- (nullable CBPeripheral *)retrievePeripheralWithIdentifier:(NSUUID *)identifier;
@end
NS_ASSUME_NONNULL_END
@@ -136,6 +136,22 @@ static GNCBLEL2CAPServer *_Nonnull CreateL2CapServer(
}
}
- (nullable CBPeripheral *)retrievePeripheralWithIdentifier:(NSUUID *)identifier {
NSAssert(_centralManager, @"CBCentralManager not created.");
NSAssert(identifier, @"Should have an identifier, self: %@", self);
NSArray<CBPeripheral *> *peripherals =
[_centralManager retrievePeripheralsWithIdentifiers:@[ identifier ]];
for (CBPeripheral *peripheral in peripherals) {
if ([peripheral.identifier isEqual:identifier]) {
return peripheral;
}
}
return nil;
}
- (BOOL)supportsExtendedAdvertisements {
// TODO(b/294736083): CoreBluetooth doesn't support actually advertising any extensions, however
// some devices can scan for them if the feature is available. If we return @c YES from this
@@ -97,6 +97,14 @@ NS_ASSUME_NONNULL_BEGIN
/** Asks the central manager to stop scanning for peripherals. */
- (void)stopScan;
/**
* Retrieves the peripherals with the given identifiers.
*
* @param identifiers The identifiers of the peripherals to retrieve.
* @return An array of peripherals with the given identifiers.
*/
- (NSArray<CBPeripheral *> *)retrievePeripheralsWithIdentifiers:(NSArray<NSUUID *> *)identifiers;
@end
/**
@@ -385,4 +385,20 @@ static NSString *const kServiceUUID = @"0000FEF3-0000-1000-8000-00805F9B34FB";
[self waitForExpectations:@[ disconnectExpectation ] timeout:3];
}
- (void)testRetrievePeripheralWithIdentifier_exists {
GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init];
GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil];
XCTAssertNotNil(
[medium retrievePeripheralWithIdentifier:
[[NSUUID alloc] initWithUUIDString:@"11111111-1111-1111-1111-111111111111"]]);
}
- (void)testRetrievePeripheralWithIdentifier_doesNotExist {
GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init];
GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil];
XCTAssertNil(
[medium retrievePeripheralWithIdentifier:
[[NSUUID alloc] initWithUUIDString:@"11111111-1111-1111-1111-111111111112"]]);
}
@end
@@ -24,6 +24,7 @@
@implementation GNCFakeCentralManager {
CBManagerState _state;
NSArray<CBUUID *> *_serviceUUIDs;
NSDictionary<NSUUID *, GNCFakePeripheral *> *_peripherals;
}
@synthesize centralDelegate;
@@ -32,6 +33,12 @@
self = [super init];
if (self) {
_state = CBManagerStateUnknown;
// Add a fake peripheral
NSUUID *identifier =
[[NSUUID alloc] initWithUUIDString:@"11111111-1111-1111-1111-111111111111"];
_peripherals = [NSMutableDictionary
dictionaryWithObject:[[GNCFakePeripheral alloc] initWithIdentifier:identifier]
forKey:identifier];
}
return self;
}
@@ -63,6 +70,16 @@
- (void)stopScan {
}
- (NSArray<CBPeripheral *> *)retrievePeripheralsWithIdentifiers:(NSArray<NSUUID *> *)identifiers {
NSMutableArray<CBPeripheral *> *peripherals = [NSMutableArray array];
for (NSUUID *identifier in identifiers) {
if (_peripherals[identifier]) {
[peripherals addObject:(CBPeripheral *)_peripherals[identifier]];
}
}
return peripherals;
}
#pragma mark - Testing Helpers
- (NSArray<CBUUID *> *)serviceUUIDs {
@@ -22,6 +22,9 @@ NS_ASSUME_NONNULL_BEGIN
/** A fake implementation of @c GNCPeripheral to inject for testing. */
@interface GNCFakePeripheral : NSObject <GNCPeripheral>
/** Initializes the fake peripheral with the given identifier. */
- (instancetype)initWithIdentifier:(NSUUID *)identifier;
/** The peripheral's delegate. */
@property(nonatomic, nullable, readwrite) id<CBPeripheralDelegate> delegate;
@@ -50,6 +50,15 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
- (instancetype)initWithIdentifier:(NSUUID *)identifier {
self = [super init];
if (self) {
_services = [[NSMutableArray alloc] init];
_identifier = identifier;
}
return self;
}
- (void)setPeripheralDelegate:(nullable id<GNCPeripheralDelegate>)peripheralDelegate {
self.delegate = peripheralDelegate;
}
@@ -552,8 +552,7 @@ static const char *const kTestServiceID = "TestServiceID";
NSString *unknownUUIDString = [[NSUUID alloc] init].UUIDString;
std::optional<nearby::api::ble::BlePeripheral::UniqueId> result2 =
_medium->RetrieveBlePeripheralIdFromNativeId([unknownUUIDString UTF8String]);
XCTAssertTrue(result2.has_value()); // Valid UUID format should return an ID.
XCTAssertNotEqual(result2.value(), fakePeripheral.identifier.hash);
XCTAssertFalse(result2.has_value());
std::optional<nearby::api::ble::BlePeripheral::UniqueId> result3 =
_medium->RetrieveBlePeripheralIdFromNativeId("invalid-uuid-string");
@@ -707,7 +707,7 @@ std::optional<api::ble::BlePeripheral::UniqueId> BleMedium::RetrieveBlePeriphera
NSUUID *uuidFromString = [[NSUUID alloc] initWithUUIDString:uuidString];
if (uuidFromString == nil) {
GNCLoggerError(@"Native BLE peripheral ID is not a valid UUID.");
GNCLoggerError(@"Native BLE peripheral ID %@ is not a valid UUID.", uuidString);
return std::nullopt;
}
@@ -718,7 +718,14 @@ std::optional<api::ble::BlePeripheral::UniqueId> BleMedium::RetrieveBlePeriphera
}
// Retrieve the BLE peripheral from CBCentralManager.
peripheral = [socketCentralManager_ retrievePeripheralWithIdentifier:uuidFromString];
peripheral = [medium_ retrievePeripheralWithIdentifier:uuidFromString];
if (peripheral == nil) {
GNCLoggerError(@"Failed to retrieve BLE peripheral from identifier: %@", uuidFromString);
return std::nullopt;
}
peripherals_.Add(peripheral);
return peripheral.identifier.hash;
}
@@ -748,7 +755,7 @@ bool BleMedium::ShouldReportAdvertisement(NSDate *now,
}
if ([now timeIntervalSinceDate:it->second.last_timestamp] < kThresholdInterval &&
it -> second.last_service_data.count == service_data.count) {
it->second.last_service_data.count == service_data.count) {
bool is_same_advertisement = true;
for (CBUUID *service_uuid in service_data.allKeys) {
if (![service_data[service_uuid] isEqualToData:it->second.last_service_data[service_uuid]]) {