Skip to content

Commit

Permalink
Use a delegate for client callbacks in the CHIP Darwin Framework (#2180)
Browse files Browse the repository at this point in the history
* Use a delegate for client callbacks in the CHIP Darwin Framework

* Restyled by clang-format

Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
sagar-apple and restyled-commits authored Aug 17, 2020
1 parent c3ca2ce commit b96e521
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 59 deletions.
49 changes: 28 additions & 21 deletions src/darwin/CHIPTool/CHIPTool/CHIPViewControllerBase.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

static NSString * const ipKey = @"ipk";

@interface CHIPViewControllerBase ()
@interface CHIPViewControllerBase () <CHIPDeviceControllerDelegate>

@property (readwrite) dispatch_queue_t chipCallbackQueue;
@property (readwrite) BOOL reconnectOnForeground;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -248,4 +229,30 @@ - (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
44 changes: 34 additions & 10 deletions src/darwin/Framework/CHIP/CHIPDeviceController.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -69,20 +71,42 @@ 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] queue The queue on which the Device Controller will deliver callbacks
*/
- (void)setDelegate:(id<CHIPDeviceControllerDelegate>)delegate queue:(dispatch_queue_t)queue;

@end

/**
* The protocol definition for the CHIPDeviceControllerDelegate
*
* All delegate methods will be called on the supplied Delegate Queue.
*/
@protocol CHIPDeviceControllerDelegate <NSObject>

/**
* Notify the delegate when a connection request succeeds
*
* @param[in] appCallbackQueue the queue that should be used to deliver the
* message/error callbacks for this consumer.
*/
- (void)deviceControllerOnConnected;

/**
* Notify the delegate that a message was received
*
* @param[in] onMessage the block to call when the controller gets a message
* from the network.
* @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

Expand Down
66 changes: 38 additions & 28 deletions src/darwin/Framework/CHIP/CHIPDeviceController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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<CHIPDeviceControllerDelegate> 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;
Expand Down Expand Up @@ -150,34 +155,37 @@ 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<CHIPDeviceControllerDelegate> 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<CHIPDeviceControllerDelegate> 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<CHIPDeviceControllerDelegate> strongDelegate = [self delegate];
if (strongDelegate && [self delegateQueue]) {
dispatch_async(self.delegateQueue, ^{
[strongDelegate deviceControllerOnConnected];
});
}
}

- (void)_manualKeyExchange:(chip::Transport::PeerConnectionState *)state
Expand Down Expand Up @@ -443,15 +451,17 @@ + (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<CHIPDeviceControllerDelegate>)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

0 comments on commit b96e521

Please sign in to comment.