Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[darwin] Update BLEScannerDelegate interface to have both a add and a… #26001

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion examples/chip-tool/commands/common/DeviceScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ void DeviceScanner::OnNodeDiscovered(const DiscoveredNodeData & nodeData)
}

#if CHIP_TOOL_DEVICE_SCANNER_USE_BLE
void DeviceScanner::OnBleScanResult(BLE_CONNECTION_OBJECT connObj, const ChipBLEDeviceIdentificationInfo & info)
void DeviceScanner::OnBleScanAdd(BLE_CONNECTION_OBJECT connObj, const ChipBLEDeviceIdentificationInfo & info)
{
auto discriminator = info.GetDeviceDiscriminator();
auto vendorId = static_cast<VendorId>(info.GetVendorId());
Expand All @@ -85,6 +85,8 @@ void DeviceScanner::OnBleScanResult(BLE_CONNECTION_OBJECT connObj, const ChipBLE
DeviceScannerResult result = { params, vendorId, productId, discriminator };
mDiscoveredResults.push_back(result);
}

void DeviceScanner::OnBleScanRemove(BLE_CONNECTION_OBJECT connObj) {}
#endif // CHIP_TOOL_DEVICE_SCANNER_USE_BLE

CHIP_ERROR DeviceScanner::Get(uint16_t index, RendezvousParameters & params)
Expand Down
3 changes: 2 additions & 1 deletion examples/chip-tool/commands/common/DeviceScanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ class DeviceScanner : public chip::Dnssd::CommissioningResolveDelegate

#if CHIP_TOOL_DEVICE_SCANNER_USE_BLE
/////////// BleScannerDelegate Interface /////////
void OnBleScanResult(BLE_CONNECTION_OBJECT connObj, const chip::Ble::ChipBLEDeviceIdentificationInfo & info) override;
void OnBleScanAdd(BLE_CONNECTION_OBJECT connObj, const chip::Ble::ChipBLEDeviceIdentificationInfo & info) override;
void OnBleScanRemove(BLE_CONNECTION_OBJECT connObj) override;
#endif // CHIP_TOOL_DEVICE_SCANNER_USE_BLE

private:
Expand Down
89 changes: 70 additions & 19 deletions src/platform/Darwin/BleConnectionDelegateImpl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@

constexpr uint64_t kScanningWithDiscriminatorTimeoutInSeconds = 60;
constexpr uint64_t kScanningWithoutDelegateTimeoutInSeconds = 120;
constexpr uint64_t kCachePeripheralTimeoutInSeconds
= static_cast<uint64_t>(CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX / 1000.0 * 8.0 * 0.625);
constexpr const char * kBleWorkQueueName = "org.csa-iot.matter.framework.ble.workqueue";

typedef NS_ENUM(uint8_t, BleConnectionMode) {
Expand All @@ -60,7 +62,7 @@ @interface BleConnection : NSObject <CBCentralManagerDelegate, CBPeripheralDeleg
@property (strong, nonatomic) CBUUID * shortServiceUUID;
@property (nonatomic, readonly, nullable) dispatch_source_t timer;
@property (nonatomic, readonly) BleConnectionMode currentMode;
@property (strong, nonatomic) NSMutableDictionary * cachedPeripherals;
@property (strong, nonatomic) NSMutableDictionary<CBPeripheral *, NSDictionary *> * cachedPeripherals;
@property (unsafe_unretained, nonatomic) bool found;
@property (unsafe_unretained, nonatomic) chip::SetupDiscriminator deviceDiscriminator;
@property (unsafe_unretained, nonatomic) void * appState;
Expand All @@ -81,6 +83,9 @@ - (void)updateWithPeripheral:(CBPeripheral *)peripheral;
- (BOOL)isScanningWithoutDelegate;
- (BOOL)isScanning;
- (BOOL)isConnecting;
- (void)addPeripheralToCache:(CBPeripheral *)peripheral data:(NSData *)data;
- (void)removePeripheralFromCache:(CBPeripheral *)peripheral;
- (void)removePeripheralsFromCache;

@end

Expand Down Expand Up @@ -376,18 +381,7 @@ - (void)centralManager:(CBCentralManager *)central
}

if (![self isConnecting]) {
if ([_cachedPeripherals objectForKey:peripheral] == nil) {
ChipLogProgress(Ble, "Storing device %p with discriminator: %d", peripheral, discriminator);
if (_scannerDelegate) {
dispatch_async(_chipWorkQueue, ^{
ChipBLEDeviceIdentificationInfo info;
memcpy(&info, bytes, sizeof(info));
_scannerDelegate->OnBleScanResult((__bridge void *) peripheral, info);
});
}
}

_cachedPeripherals[peripheral] = serviceData;
[self addPeripheralToCache:peripheral data:serviceData];
}
}

Expand Down Expand Up @@ -539,9 +533,9 @@ - (void)start
- (void)stop
{
[self stopScanning];
_scannerDelegate = nil;
[_cachedPeripherals removeAllObjects];
[self removePeripheralsFromCache];
_cachedPeripherals = nil;
_scannerDelegate = nil;

if (!_centralManager || !_peripheral) {
return;
Expand Down Expand Up @@ -594,17 +588,16 @@ - (void)connect:(CBPeripheral *)peripheral

- (void)updateWithDelegate:(chip::DeviceLayer::BleScannerDelegate *)delegate
{
[_cachedPeripherals removeAllObjects];
_scannerDelegate = delegate;
_currentMode = (delegate == nullptr) ? kScanningWithoutDelegate : kScanning;

if (_currentMode == kScanning) {
for (CBPeripheral * cachedPeripheral in _cachedPeripherals) {
NSData * serviceData = _cachedPeripherals[cachedPeripheral];
NSData * serviceData = _cachedPeripherals[cachedPeripheral][@"data"];
dispatch_async(_chipWorkQueue, ^{
ChipBLEDeviceIdentificationInfo info;
memcpy(&info, [serviceData bytes], sizeof(info));
_scannerDelegate->OnBleScanResult((__bridge void *) cachedPeripheral, info);
_scannerDelegate->OnBleScanAdd((__bridge void *) cachedPeripheral, info);
});
}
}
Expand All @@ -620,7 +613,7 @@ - (void)updateWithDiscriminator:(const chip::SetupDiscriminator &)deviceDiscrimi

CBPeripheral * peripheral = nil;
for (CBPeripheral * cachedPeripheral in _cachedPeripherals) {
NSData * serviceData = _cachedPeripherals[cachedPeripheral];
NSData * serviceData = _cachedPeripherals[cachedPeripheral][@"data"];
ChipBLEDeviceIdentificationInfo info;
memcpy(&info, [serviceData bytes], sizeof(info));

Expand All @@ -630,6 +623,8 @@ - (void)updateWithDiscriminator:(const chip::SetupDiscriminator &)deviceDiscrimi
}
}

[self removePeripheralsFromCache];
vivien-apple marked this conversation as resolved.
Show resolved Hide resolved

if (peripheral) {
ChipLogProgress(Ble, "Connecting to cached device: %p", peripheral);
[self connect:peripheral];
Expand All @@ -649,6 +644,62 @@ - (void)updateWithPeripheral:(CBPeripheral *)peripheral
[self stopScanning];
}

- (void)addPeripheralToCache:(CBPeripheral *)peripheral data:(NSData *)data
{
dispatch_source_t timeoutTimer;
vivien-apple marked this conversation as resolved.
Show resolved Hide resolved

if ([_cachedPeripherals objectForKey:peripheral]) {
timeoutTimer = _cachedPeripherals[peripheral][@"timer"];
} else {
auto delegate = _scannerDelegate;
if (delegate) {
dispatch_async(_chipWorkQueue, ^{
ChipBLEDeviceIdentificationInfo info;
auto bytes = (const uint8_t *) [data bytes];
memcpy(&info, bytes, sizeof(info));
delegate->OnBleScanAdd((__bridge void *) peripheral, info);
});
}

timeoutTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _workQueue);
dispatch_source_set_event_handler(timeoutTimer, ^{
[self removePeripheralFromCache:peripheral];
});
dispatch_resume(timeoutTimer);
}

auto timeout = static_cast<int64_t>(kCachePeripheralTimeoutInSeconds * NSEC_PER_SEC);
dispatch_source_set_timer(timeoutTimer, dispatch_walltime(nullptr, timeout), DISPATCH_TIME_FOREVER, 5 * NSEC_PER_SEC);

_cachedPeripherals[peripheral] = @{
@"data" : data,
@"timer" : timeoutTimer,
};
}

- (void)removePeripheralFromCache:(CBPeripheral *)peripheral
{
auto entry = [_cachedPeripherals objectForKey:peripheral];
if (entry) {
dispatch_source_cancel(entry[@"timer"]);
[_cachedPeripherals removeObjectForKey:peripheral];

auto delegate = _scannerDelegate;
if (delegate) {
dispatch_async(_chipWorkQueue, ^{
delegate->OnBleScanRemove((__bridge void *) peripheral);
});
}
}
}

- (void)removePeripheralsFromCache
{
for (CBPeripheral * peripheral in _cachedPeripherals) {
[self removePeripheralFromCache:peripheral];
}
}

/**
* private static method to copy service and characteristic UUIDs from CBCharacteristic to a pair of ChipBleUUID objects.
* this is used in calls into Chip layer to decouple it from CoreBluetooth
Expand Down
5 changes: 4 additions & 1 deletion src/platform/Darwin/BleScannerDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ class DLL_EXPORT BleScannerDelegate
virtual ~BleScannerDelegate() {}

// Called when a scan result is available.
virtual void OnBleScanResult(BLE_CONNECTION_OBJECT connObj, const Ble::ChipBLEDeviceIdentificationInfo & info) = 0;
virtual void OnBleScanAdd(BLE_CONNECTION_OBJECT connObj, const Ble::ChipBLEDeviceIdentificationInfo & info) = 0;

// Called when a scan result is not available anymore.
virtual void OnBleScanRemove(BLE_CONNECTION_OBJECT connObj) = 0;
};

} // namespace DeviceLayer
Expand Down