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

Use a delegate for client callbacks in the CHIP Darwin Framework #2180

Merged
merged 2 commits into from
Aug 17, 2020
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
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