Skip to content

Commit

Permalink
[darwin] Ensure the ble timeout for scanning is resumed before trying…
Browse files Browse the repository at this point in the history
… to suspend it (#26749)
  • Loading branch information
vivien-apple authored and pull[bot] committed Oct 17, 2023
1 parent 2b4a518 commit 5329380
Showing 1 changed file with 36 additions and 30 deletions.
66 changes: 36 additions & 30 deletions src/platform/Darwin/BleConnectionDelegateImpl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -226,16 +226,10 @@ - (id)initWithQueue:(dispatch_queue_t)queue
self.shortServiceUUID = [UUIDHelper GetShortestServiceUUID:&chip::Ble::CHIP_BLE_SVC_ID];
_chipWorkQueue = chip::DeviceLayer::PlatformMgrImpl().GetWorkQueue();
_workQueue = queue;
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
_centralManager = [CBCentralManager alloc];
_found = false;
_cachedPeripherals = [[NSMutableDictionary alloc] init];
_currentMode = kUndefined;

dispatch_source_set_event_handler(_timer, ^{
[self stop];
[self dispatchConnectionError:BLE_ERROR_APP_CLOSED_CONNECTION];
});
}

return self;
Expand All @@ -247,7 +241,9 @@ - (id)initWithDelegate:(chip::DeviceLayer::BleScannerDelegate *)delegate queue:(
if (self) {
_scannerDelegate = delegate;
_currentMode = (delegate == nullptr) ? kScanningWithoutDelegate : kScanning;
[self resetTimer];
if (_currentMode == kScanningWithoutDelegate) {
[self setupTimer:kScanningWithoutDelegateTimeoutInSeconds];
}
}

return self;
Expand All @@ -259,7 +255,7 @@ - (id)initWithDiscriminator:(const chip::SetupDiscriminator &)deviceDiscriminato
if (self) {
_deviceDiscriminator = deviceDiscriminator;
_currentMode = kConnecting;
[self resetTimer];
[self setupTimer:kScanningWithDiscriminatorTimeoutInSeconds];
}

return self;
Expand All @@ -280,20 +276,26 @@ - (BOOL)isConnecting
return _currentMode == kConnecting;
}

- (void)resetTimer
- (void)setupTimer:(uint64_t)timeout
{
if ([self isConnecting]) {
auto timeout = static_cast<int64_t>(kScanningWithDiscriminatorTimeoutInSeconds * NSEC_PER_SEC);
dispatch_source_set_timer(_timer, dispatch_walltime(nullptr, timeout), DISPATCH_TIME_FOREVER, 5 * NSEC_PER_SEC);
} else if ([self isScanningWithoutDelegate]) {
auto timeout = static_cast<int64_t>(kScanningWithoutDelegateTimeoutInSeconds * NSEC_PER_SEC);
dispatch_source_set_timer(_timer, dispatch_walltime(nullptr, timeout), DISPATCH_TIME_FOREVER, 5 * NSEC_PER_SEC);
} else if ([self isScanning]) {
dispatch_source_cancel(_timer);
} else {
// It should not happens.
[self clearTimer];

_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _workQueue);
dispatch_source_set_event_handler(_timer, ^{
[self stop];
[self dispatchConnectionError:CHIP_ERROR_INCORRECT_STATE];
[self dispatchConnectionError:BLE_ERROR_APP_CLOSED_CONNECTION];
});

auto value = static_cast<int64_t>(timeout * NSEC_PER_SEC);
dispatch_source_set_timer(_timer, dispatch_walltime(nullptr, value), DISPATCH_TIME_FOREVER, 5 * NSEC_PER_SEC);
dispatch_resume(_timer);
}

- (void)clearTimer
{
if (_timer) {
dispatch_source_cancel(_timer);
_timer = nil;
}
}

Expand Down Expand Up @@ -544,8 +546,6 @@ - (void)peripheral:(CBPeripheral *)peripheral

- (void)start
{
dispatch_resume(_timer);

// If a peripheral has already been found, try to connect to it once BLE starts,
// otherwise start scanning to find the peripheral to connect to.
if (_peripheral != nil) {
Expand All @@ -557,12 +557,12 @@ - (void)start

- (void)stop
{
_scannerDelegate = nil;
_found = false;
[self stopScanning];
[self removePeripheralsFromCache];
_cachedPeripherals = nil;
_scannerDelegate = nil;

if (!_centralManager || !_peripheral) {
if (!_centralManager && !_peripheral) {
return;
}

Expand All @@ -573,12 +573,15 @@ - (void)stop
// able to reach those.
// This is why closing connections happens as 2 async steps.
dispatch_async(_chipWorkQueue, ^{
_mBleLayer->CloseAllBleConnections();
if (_peripheral) {
_mBleLayer->CloseAllBleConnections();
}

dispatch_async(_workQueue, ^{
_centralManager.delegate = nil;
_centralManager = nil;
_peripheral = nil;
chip::DeviceLayer::Internal::ble = nil;
});
});
}
Expand All @@ -598,7 +601,8 @@ - (void)stopScanning
if (!_centralManager) {
return;
}
dispatch_source_cancel(_timer);

[self clearTimer];
[_centralManager stopScan];
}

Expand All @@ -618,6 +622,8 @@ - (void)updateWithDelegate:(chip::DeviceLayer::BleScannerDelegate *)delegate
_currentMode = (delegate == nullptr) ? kScanningWithoutDelegate : kScanning;

if (_currentMode == kScanning) {
[self clearTimer];

for (CBPeripheral * cachedPeripheral in _cachedPeripherals) {
NSData * serviceData = _cachedPeripherals[cachedPeripheral][@"data"];
dispatch_async(_chipWorkQueue, ^{
Expand All @@ -626,9 +632,9 @@ - (void)updateWithDelegate:(chip::DeviceLayer::BleScannerDelegate *)delegate
_scannerDelegate->OnBleScanAdd((__bridge void *) cachedPeripheral, info);
});
}
} else {
[self setupTimer:kScanningWithoutDelegateTimeoutInSeconds];
}

[self resetTimer];
}

- (void)updateWithDiscriminator:(const chip::SetupDiscriminator &)deviceDiscriminator
Expand Down Expand Up @@ -656,7 +662,7 @@ - (void)updateWithDiscriminator:(const chip::SetupDiscriminator &)deviceDiscrimi
[self connect:peripheral];
[self stopScanning];
} else {
[self resetTimer];
[self setupTimer:kScanningWithDiscriminatorTimeoutInSeconds];
}
}

Expand Down

0 comments on commit 5329380

Please sign in to comment.