From a9b381b6f3a92d609c07468eee657a00e0ec18fb Mon Sep 17 00:00:00 2001 From: Bliss Chapman Date: Tue, 5 Sep 2023 18:51:45 -0700 Subject: [PATCH 1/2] [MacOS] Add timeout to connect --- .../src/backends/macos/PeripheralBaseMacOS.h | 1 + .../src/backends/macos/PeripheralBaseMacOS.mm | 23 ++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/simpleble/src/backends/macos/PeripheralBaseMacOS.h b/simpleble/src/backends/macos/PeripheralBaseMacOS.h index 41370bdb..a085992f 100644 --- a/simpleble/src/backends/macos/PeripheralBaseMacOS.h +++ b/simpleble/src/backends/macos/PeripheralBaseMacOS.h @@ -19,6 +19,7 @@ - (uint16_t)mtu; - (void)connect; +- (void)connectWithTimeout:(NSTimeInterval)timeout; - (void)disconnect; - (bool)isConnected; - (std::vector)getServices; diff --git a/simpleble/src/backends/macos/PeripheralBaseMacOS.mm b/simpleble/src/backends/macos/PeripheralBaseMacOS.mm index 2d137b16..bc4705a4 100644 --- a/simpleble/src/backends/macos/PeripheralBaseMacOS.mm +++ b/simpleble/src/backends/macos/PeripheralBaseMacOS.mm @@ -19,6 +19,23 @@ } \ } while (0) +#define WAIT_UNTIL_FALSE_WITH_TIMEOUT(obj, var, timeout) \ + do { \ + BOOL _tmpVar = YES; \ + auto _timeout = std::chrono::duration(timeout); \ + auto _start = std::chrono::steady_clock::now(); \ + while (_tmpVar) { \ + [NSThread sleepForTimeInterval:0.01]; \ + @synchronized(obj) { \ + _tmpVar = (var); \ + } \ + auto _duration = std::chrono::steady_clock::now() - _start; \ + if (_duration > _timeout) { \ + break; \ + } \ + } \ + } while (0) + // -------------------------------------------------- @interface BleTask : NSObject @@ -126,6 +143,10 @@ - (uint16_t)mtu { } - (void)connect { + [self connectWithTimeout:5]; +} + +- (void)connectWithTimeout:(NSTimeInterval)timeout { @synchronized(_task) { // --- Connect to the peripheral --- @synchronized(self) { @@ -134,7 +155,7 @@ - (void)connect { [self.centralManager connectPeripheral:self.peripheral options:@{}]; // TODO: Do we need to pass any options? } - WAIT_UNTIL_FALSE(self, _task.pending); + WAIT_UNTIL_FALSE_WITH_TIMEOUT(self, _task.pending, timeout); if (self.peripheral.state != CBPeripheralStateConnected || _task.error != nil) { [self throwBasedOnError:_task.error withFormat:@"Peripheral Connection"]; From 4335f0dec4f7b0218a0298a2a3354fefe38053a9 Mon Sep 17 00:00:00 2001 From: Kevin Dewald <5274600+kdewald@users.noreply.github.com> Date: Wed, 6 Sep 2023 16:40:38 -0700 Subject: [PATCH 2/2] Made my suggested changes. --- .../src/backends/macos/PeripheralBaseMacOS.h | 1 - .../src/backends/macos/PeripheralBaseMacOS.mm | 15 +++------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/simpleble/src/backends/macos/PeripheralBaseMacOS.h b/simpleble/src/backends/macos/PeripheralBaseMacOS.h index a085992f..41370bdb 100644 --- a/simpleble/src/backends/macos/PeripheralBaseMacOS.h +++ b/simpleble/src/backends/macos/PeripheralBaseMacOS.h @@ -19,7 +19,6 @@ - (uint16_t)mtu; - (void)connect; -- (void)connectWithTimeout:(NSTimeInterval)timeout; - (void)disconnect; - (bool)isConnected; - (std::vector)getServices; diff --git a/simpleble/src/backends/macos/PeripheralBaseMacOS.mm b/simpleble/src/backends/macos/PeripheralBaseMacOS.mm index bc4705a4..a4262fd7 100644 --- a/simpleble/src/backends/macos/PeripheralBaseMacOS.mm +++ b/simpleble/src/backends/macos/PeripheralBaseMacOS.mm @@ -22,17 +22,12 @@ #define WAIT_UNTIL_FALSE_WITH_TIMEOUT(obj, var, timeout) \ do { \ BOOL _tmpVar = YES; \ - auto _timeout = std::chrono::duration(timeout); \ - auto _start = std::chrono::steady_clock::now(); \ - while (_tmpVar) { \ + NSDate* endDate = [NSDate dateWithTimeInterval:timeout sinceDate:NSDate.now]; \ + while (_tmpVar && [NSDate.now compare:endDate] == NSOrderedAscending) { \ [NSThread sleepForTimeInterval:0.01]; \ @synchronized(obj) { \ _tmpVar = (var); \ } \ - auto _duration = std::chrono::steady_clock::now() - _start; \ - if (_duration > _timeout) { \ - break; \ - } \ } \ } while (0) @@ -143,10 +138,6 @@ - (uint16_t)mtu { } - (void)connect { - [self connectWithTimeout:5]; -} - -- (void)connectWithTimeout:(NSTimeInterval)timeout { @synchronized(_task) { // --- Connect to the peripheral --- @synchronized(self) { @@ -155,7 +146,7 @@ - (void)connectWithTimeout:(NSTimeInterval)timeout { [self.centralManager connectPeripheral:self.peripheral options:@{}]; // TODO: Do we need to pass any options? } - WAIT_UNTIL_FALSE_WITH_TIMEOUT(self, _task.pending, timeout); + WAIT_UNTIL_FALSE_WITH_TIMEOUT(self, _task.pending, 5.0); if (self.peripheral.state != CBPeripheralStateConnected || _task.error != nil) { [self throwBasedOnError:_task.error withFormat:@"Peripheral Connection"];