From f586c4055308b99788f653ae1a61e16ed43db0e7 Mon Sep 17 00:00:00 2001 From: Sagar Dhawan Date: Fri, 14 Aug 2020 13:54:17 -0700 Subject: [PATCH 1/2] Use a delegate for client callbacks in the CHIP Darwin Framework --- .../CHIPTool/CHIPViewControllerBase.m | 46 ++++++------ .../Framework/CHIP/CHIPDeviceController.h | 45 +++++++++--- .../Framework/CHIP/CHIPDeviceController.mm | 72 +++++++++++-------- 3 files changed, 104 insertions(+), 59 deletions(-) diff --git a/src/darwin/CHIPTool/CHIPTool/CHIPViewControllerBase.m b/src/darwin/CHIPTool/CHIPTool/CHIPViewControllerBase.m index f0979d3d0f82ce..3d630e4de44ab9 100644 --- a/src/darwin/CHIPTool/CHIPTool/CHIPViewControllerBase.m +++ b/src/darwin/CHIPTool/CHIPTool/CHIPViewControllerBase.m @@ -24,7 +24,7 @@ static NSString * const ipKey = @"ipk"; -@interface CHIPViewControllerBase () +@interface CHIPViewControllerBase () @property (readwrite) dispatch_queue_t chipCallbackQueue; @property (readwrite) BOOL reconnectOnForeground; @@ -53,28 +53,9 @@ - (void)viewDidLoad [self.view addGestureRecognizer:tap]; // initialize the device controller - __weak typeof(self) weakSelf = self; dispatch_queue_t callbackQueue = dispatch_queue_create("com.zigbee.chip.example.callback", DISPATCH_QUEUE_SERIAL); self.chipController = [CHIPDeviceController sharedController]; - [self.chipController registerCallbacks:callbackQueue - onConnected:^(void) { - typeof(self) strongSelf = weakSelf; - [strongSelf postConnected]; - } - onMessage:^(NSData * _Nonnull message) { - typeof(self) strongSelf = weakSelf; - if ([CHIPDeviceController isDataModelCommand:message] == YES) { - NSString * strMessage = [CHIPDeviceController commandToString:message]; - [strongSelf postResult:strMessage]; - } else { - NSString * strMessage = [[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding]; - [strongSelf postResult:strMessage]; - } - } - onError:^(NSError * _Nonnull error) { - typeof(self) strongSelf = weakSelf; - [strongSelf postError:error.localizedDescription]; - }]; + [self.chipController setDelegate:self queue:callbackQueue]; // need to restart connections on background/foreground transitions otherwise the socket can be closed without CHIP knowing // about it. @@ -248,4 +229,27 @@ - (void)viewDidDisappear:(BOOL)animated } } +#if 0 +#pragma mark - +#pragma mark == CHIPDeviceControllerDelegate Methods == +#endif + +- (void)deviceControllerOnConnected { + [self postConnected]; +} + +- (void)deviceControllerOnMessage:(NSData *)message { + if ([CHIPDeviceController isDataModelCommand:message] == YES) { + NSString * strMessage = [CHIPDeviceController commandToString:message]; + [self postResult:strMessage]; + } else { + NSString * strMessage = [[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding]; + [self postResult:strMessage]; + } +} + +- (void)deviceControllerOnError:(NSError *)error { + [self postError:error.localizedDescription]; +} + @end diff --git a/src/darwin/Framework/CHIP/CHIPDeviceController.h b/src/darwin/Framework/CHIP/CHIPDeviceController.h index 48c15019d590c3..6c7c5f95ba4c9f 100644 --- a/src/darwin/Framework/CHIP/CHIPDeviceController.h +++ b/src/darwin/Framework/CHIP/CHIPDeviceController.h @@ -27,6 +27,8 @@ typedef void (^ControllerOnConnectedBlock)(void); typedef void (^ControllerOnMessageBlock)(NSData * message); typedef void (^ControllerOnErrorBlock)(NSError * error); +@protocol CHIPDeviceControllerDelegate; + @interface AddressInfo : NSObject @property (readonly, copy) NSString * ip; @@ -69,20 +71,43 @@ typedef void (^ControllerOnErrorBlock)(NSError * error); + (CHIPDeviceController *)sharedController; /** - * Register callbacks for network activity. + * Set the Delegate for the Device Controller as well as the Queue on which the Delegate callbacks will be triggered + * + * @param[in] delegate The delegate the Device Controller should use * - * @param[in] appCallbackQueue the queue that should be used to deliver the - * message/error callbacks for this consumer. + * @param[in] queue The queue on which the Device Controller will deliver callbacks + */ +- (void)setDelegate:(id)delegate queue:(dispatch_queue_t)queue; + +@end + + +/** + * The protocol definition for the CHIPDeviceControllerDelegate * - * @param[in] onMessage the block to call when the controller gets a message - * from the network. + * All delegate methods will be called on the supplied Delegate Queue. + */ +@protocol CHIPDeviceControllerDelegate + +/** + * Notify the delegate when a connection request succeeds + * + */ +- (void)deviceControllerOnConnected; + +/** + * Notify the delegate that a message was received + * + * @param[in] message The received message + */ +- (void)deviceControllerOnMessage:(NSData *)message; + +/** + * Notify the Delegate that an error occurred * - * @param[in] onError the block to call when there is a network error. + * @param[in] error The error that occurred */ -- (void)registerCallbacks:(dispatch_queue_t)appCallbackQueue - onConnected:(ControllerOnConnectedBlock)onConnected - onMessage:(ControllerOnMessageBlock)onMessage - onError:(ControllerOnErrorBlock)onError; +- (void)deviceControllerOnError:(NSError *)error; @end diff --git a/src/darwin/Framework/CHIP/CHIPDeviceController.mm b/src/darwin/Framework/CHIP/CHIPDeviceController.mm index feeedc413c2f82..a3bc3639bf36b6 100644 --- a/src/darwin/Framework/CHIP/CHIPDeviceController.mm +++ b/src/darwin/Framework/CHIP/CHIPDeviceController.mm @@ -52,11 +52,16 @@ @interface CHIPDeviceController () // queue used to call select on the system and inet layer fds., remove this with NW Framework. // primarily used to not block the work queue @property (atomic, readonly) dispatch_queue_t chipSelectQueue; -// queue used to signal callbacks to the application -@property (readwrite) dispatch_queue_t appCallbackQueue; -@property (readwrite) ControllerOnConnectedBlock onConnectedHandler; -@property (readwrite) ControllerOnMessageBlock onMessageHandler; -@property (readwrite) ControllerOnErrorBlock onErrorHandler; +/** + * The Controller delegate. + * Note: Getter is not thread safe. + */ +@property (readonly, weak, nonatomic) id delegate; + +/** + * The delegate queue where delegate callbacks will run + */ +@property (readonly, nonatomic) dispatch_queue_t delegateQueue; @property (readonly) chip::DeviceController::ChipDeviceController * cppController; @property (readwrite) NSData * localKey; @property (readwrite) NSData * peerKey; @@ -150,34 +155,40 @@ static void onInternalError(chip::DeviceController::ChipDeviceController * devic - (void)_dispatchAsyncErrorBlock:(NSError *)error { CHIP_LOG_METHOD_ENTRY(); - // to avoid retaining "self" - ControllerOnErrorBlock onErrorHandler = self.onErrorHandler; - dispatch_async(_appCallbackQueue, ^() { - onErrorHandler(error); - }); + id strongDelegate = [self delegate]; + if (strongDelegate && [self delegateQueue]) + { + dispatch_async(self.delegateQueue, ^{ + [strongDelegate deviceControllerOnError:error]; + }); + } } - (void)_dispatchAsyncMessageBlock:(NSData *)data { CHIP_LOG_METHOD_ENTRY(); - // to avoid retaining "self" - ControllerOnMessageBlock onMessageHandler = self.onMessageHandler; - dispatch_async(_appCallbackQueue, ^() { - onMessageHandler(data); - }); + id strongDelegate = [self delegate]; + if (strongDelegate && [self delegateQueue]) + { + dispatch_async(self.delegateQueue, ^{ + [strongDelegate deviceControllerOnMessage:data]; + }); + } } - (void)_dispatchAsyncConnectBlock { CHIP_LOG_METHOD_ENTRY(); - // to avoid retaining "self" - ControllerOnConnectedBlock onConnectedHandler = self.onConnectedHandler; - dispatch_async(_appCallbackQueue, ^() { - onConnectedHandler(); - }); + id strongDelegate = [self delegate]; + if (strongDelegate && [self delegateQueue]) + { + dispatch_async(self.delegateQueue, ^{ + [strongDelegate deviceControllerOnConnected]; + }); + } } - (void)_manualKeyExchange:(chip::Transport::PeerConnectionState *)state @@ -443,15 +454,20 @@ + (NSString *)commandToString:(NSData * _Nonnull)response return [NSString stringWithFormat:@"Sending '%@' command %@", command, status]; } -- (void)registerCallbacks:appCallbackQueue - onConnected:(ControllerOnConnectedBlock)onConnected - onMessage:(ControllerOnMessageBlock)onMessage - onError:(ControllerOnErrorBlock)onError +- (void)setDelegate:(id)delegate queue:(dispatch_queue_t)queue { - self.appCallbackQueue = appCallbackQueue; - self.onConnectedHandler = onConnected; - self.onMessageHandler = onMessage; - self.onErrorHandler = onError; + [self.lock lock]; + if ( delegate && queue ) + { + self->_delegate = delegate; + self->_delegateQueue = queue; + } + else + { + self->_delegate = nil; + self->_delegateQueue = NULL; + } + [self.lock unlock]; } @end From 319367f41ac1e799c65ff7341d45a8bf343e26c5 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Fri, 14 Aug 2020 21:09:55 +0000 Subject: [PATCH 2/2] Restyled by clang-format --- .../CHIPTool/CHIPTool/CHIPViewControllerBase.m | 9 ++++++--- src/darwin/Framework/CHIP/CHIPDeviceController.h | 1 - .../Framework/CHIP/CHIPDeviceController.mm | 16 +++++----------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/darwin/CHIPTool/CHIPTool/CHIPViewControllerBase.m b/src/darwin/CHIPTool/CHIPTool/CHIPViewControllerBase.m index 3d630e4de44ab9..fa882076b4bfd1 100644 --- a/src/darwin/CHIPTool/CHIPTool/CHIPViewControllerBase.m +++ b/src/darwin/CHIPTool/CHIPTool/CHIPViewControllerBase.m @@ -234,11 +234,13 @@ - (void)viewDidDisappear:(BOOL)animated #pragma mark == CHIPDeviceControllerDelegate Methods == #endif -- (void)deviceControllerOnConnected { +- (void)deviceControllerOnConnected +{ [self postConnected]; } -- (void)deviceControllerOnMessage:(NSData *)message { +- (void)deviceControllerOnMessage:(NSData *)message +{ if ([CHIPDeviceController isDataModelCommand:message] == YES) { NSString * strMessage = [CHIPDeviceController commandToString:message]; [self postResult:strMessage]; @@ -248,7 +250,8 @@ - (void)deviceControllerOnMessage:(NSData *)message { } } -- (void)deviceControllerOnError:(NSError *)error { +- (void)deviceControllerOnError:(NSError *)error +{ [self postError:error.localizedDescription]; } diff --git a/src/darwin/Framework/CHIP/CHIPDeviceController.h b/src/darwin/Framework/CHIP/CHIPDeviceController.h index 6c7c5f95ba4c9f..2d5d96c3a6faa4 100644 --- a/src/darwin/Framework/CHIP/CHIPDeviceController.h +++ b/src/darwin/Framework/CHIP/CHIPDeviceController.h @@ -81,7 +81,6 @@ typedef void (^ControllerOnErrorBlock)(NSError * error); @end - /** * The protocol definition for the CHIPDeviceControllerDelegate * diff --git a/src/darwin/Framework/CHIP/CHIPDeviceController.mm b/src/darwin/Framework/CHIP/CHIPDeviceController.mm index a3bc3639bf36b6..6cd810a3341688 100644 --- a/src/darwin/Framework/CHIP/CHIPDeviceController.mm +++ b/src/darwin/Framework/CHIP/CHIPDeviceController.mm @@ -157,8 +157,7 @@ - (void)_dispatchAsyncErrorBlock:(NSError *)error CHIP_LOG_METHOD_ENTRY(); id strongDelegate = [self delegate]; - if (strongDelegate && [self delegateQueue]) - { + if (strongDelegate && [self delegateQueue]) { dispatch_async(self.delegateQueue, ^{ [strongDelegate deviceControllerOnError:error]; }); @@ -170,8 +169,7 @@ - (void)_dispatchAsyncMessageBlock:(NSData *)data CHIP_LOG_METHOD_ENTRY(); id strongDelegate = [self delegate]; - if (strongDelegate && [self delegateQueue]) - { + if (strongDelegate && [self delegateQueue]) { dispatch_async(self.delegateQueue, ^{ [strongDelegate deviceControllerOnMessage:data]; }); @@ -183,8 +181,7 @@ - (void)_dispatchAsyncConnectBlock CHIP_LOG_METHOD_ENTRY(); id strongDelegate = [self delegate]; - if (strongDelegate && [self delegateQueue]) - { + if (strongDelegate && [self delegateQueue]) { dispatch_async(self.delegateQueue, ^{ [strongDelegate deviceControllerOnConnected]; }); @@ -457,13 +454,10 @@ + (NSString *)commandToString:(NSData * _Nonnull)response - (void)setDelegate:(id)delegate queue:(dispatch_queue_t)queue { [self.lock lock]; - if ( delegate && queue ) - { + if (delegate && queue) { self->_delegate = delegate; self->_delegateQueue = queue; - } - else - { + } else { self->_delegate = nil; self->_delegateQueue = NULL; }