diff --git a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.h b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.h index 0bdae1b4551936..70c3431627eecf 100644 --- a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.h +++ b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.h @@ -31,8 +31,9 @@ void CHIPSetDomainValueForKey(NSString * domain, NSString * key, id value); void CHIPRemoveDomainValueForKey(NSString * domain, NSString * key); uint64_t CHIPGetNextAvailableDeviceID(void); void CHIPSetNextAvailableDeviceID(uint64_t id); -CHIPDevice * CHIPGetPairedDevice(void); -CHIPDevice * CHIPGetPairedDeviceWithID(uint64_t id); +BOOL CHIPIsDevicePaired(uint64_t id); +BOOL CHIPGetConnectedDevice(CHIPDeviceConnectionCallback completionHandler); +BOOL CHIPGetConnectedDeviceWithID(uint64_t deviceId, CHIPDeviceConnectionCallback completionHandler); void CHIPUnpairDeviceWithID(uint64_t deviceId); @interface CHIPToolPersistentStorageDelegate : NSObject diff --git a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m index d78057edf078cf..f8e7cf598455cb 100644 --- a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m +++ b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m @@ -76,33 +76,46 @@ void CHIPSetNextAvailableDeviceID(uint64_t id) return controller; } -CHIPDevice * CHIPGetPairedDevice(void) +BOOL CHIPGetConnectedDevice(CHIPDeviceConnectionCallback completionHandler) { CHIPDeviceController * controller = InitializeCHIP(); - CHIPDevice * device = nil; uint64_t deviceId = CHIPGetNextAvailableDeviceID(); if (deviceId > 1) { // Let's use the last device that was paired deviceId--; NSError * error; - device = [controller getPairedDevice:deviceId error:&error]; + return [controller getConnectedDevice:deviceId + completionHandler:completionHandler + queue:dispatch_get_main_queue() + error:&error]; } - return device; + return NO; } -CHIPDevice * CHIPGetPairedDeviceWithID(uint64_t deviceId) +BOOL CHIPGetConnectedDeviceWithID(uint64_t deviceId, CHIPDeviceConnectionCallback completionHandler) { CHIPDeviceController * controller = InitializeCHIP(); NSError * error; - CHIPDevice * device = [controller getPairedDevice:deviceId error:&error]; + return [controller getConnectedDevice:deviceId + completionHandler:completionHandler + queue:dispatch_get_main_queue() + error:&error]; +} + +BOOL CHIPIsDevicePaired(uint64_t deviceId) +{ + CHIPDeviceController * controller = InitializeCHIP(); + + NSError * error; + bool paired = [controller isDevicePaired:deviceId error:&error]; if (error.code != CHIPSuccess) { - NSLog(@"Got back error retrieve device with deviceId %llu", deviceId); - return nil; + NSLog(@"Error retrieving device info for deviceId %llu", deviceId); + paired = NO; } - return device; + return paired; } void CHIPUnpairDeviceWithID(uint64_t deviceId) diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/Bindings/BindingsViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/Bindings/BindingsViewController.m index ec42a43932b08c..0b520bb90b808e 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/Bindings/BindingsViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/Bindings/BindingsViewController.m @@ -24,8 +24,6 @@ @interface BindingsViewController () @property (nonatomic, strong) UITextField * groupIDTextField; @property (nonatomic, strong) UITextField * endpointIDTextField; @property (nonatomic, strong) UITextField * clusterIDTextField; - -@property (nonatomic, strong) CHIPBinding * cluster; @end @implementation BindingsViewController @@ -37,8 +35,6 @@ - (void)viewDidLoad UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)]; [self.view addGestureRecognizer:tap]; - - self.cluster = [[CHIPBinding alloc] initWithDevice:CHIPGetPairedDevice() endpoint:0 queue:dispatch_get_main_queue()]; } - (void)dismissKeyboard @@ -140,15 +136,27 @@ - (IBAction)bind:(id)sender int groupId = [_groupIDTextField.text intValue]; int clusterId = [_clusterIDTextField.text intValue]; - [self.cluster bind:nodeId - groupId:groupId - endpointId:endpointId - clusterId:clusterId - responseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { - NSString * resultString - = (error == nil) ? @"Bind command: success!" : [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code]; - NSLog(resultString, nil); - }]; + if (CHIPGetConnectedDevice(^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + CHIPBinding * cluster = [[CHIPBinding alloc] initWithDevice:chipDevice endpoint:0 queue:dispatch_get_main_queue()]; + [cluster bind:nodeId + groupId:groupId + endpointId:endpointId + clusterId:clusterId + responseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { + NSString * resultString = (error == nil) + ? @"Bind command: success!" + : [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code]; + NSLog(resultString, nil); + }]; + } else { + NSLog(@"Status: Failed to establish a connection with the device"); + } + })) { + NSLog(@"Status: Waiting for connection with the device"); + } else { + NSLog(@"Status: Failed to trigger the connection with the device"); + } } - (IBAction)unbind:(id)sender @@ -158,15 +166,27 @@ - (IBAction)unbind:(id)sender int groupId = [_groupIDTextField.text intValue]; int clusterId = [_clusterIDTextField.text intValue]; - [self.cluster unbind:nodeId - groupId:groupId - endpointId:endpointId - clusterId:clusterId - responseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { - NSString * resultString = (error == nil) ? @"Unbind command: success!" - : [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code]; - NSLog(resultString, nil); - }]; + if (CHIPGetConnectedDevice(^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + CHIPBinding * cluster = [[CHIPBinding alloc] initWithDevice:chipDevice endpoint:0 queue:dispatch_get_main_queue()]; + [cluster unbind:nodeId + groupId:groupId + endpointId:endpointId + clusterId:clusterId + responseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { + NSString * resultString = (error == nil) + ? @"Unbind command: success!" + : [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code]; + NSLog(resultString, nil); + }]; + } else { + NSLog(@"Status: Failed to establish a connection with the device"); + } + })) { + NSLog(@"Status: Waiting for connection with the device"); + } else { + NSLog(@"Status: Failed to trigger the connection with the device"); + } } @end diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.m index 770db8c69de9fe..d970bda777fdb8 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/DeviceSelector.m @@ -44,7 +44,7 @@ - (void)refreshDeviceList uint64_t nextDeviceID = CHIPGetNextAvailableDeviceID(); _deviceList = [NSMutableArray new]; for (uint64_t i = 0; i < nextDeviceID; i++) { - if (CHIPGetPairedDeviceWithID(i) != nil) { + if (CHIPIsDevicePaired(i)) { [_deviceList addObject:[@(i) stringValue]]; } } diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/Echo client/EchoViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/Echo client/EchoViewController.m index d95b1611bf021c..ea686121d2cbb0 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/Echo client/EchoViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/Echo client/EchoViewController.m @@ -28,8 +28,6 @@ @interface EchoViewController () @property (nonatomic, strong) UILabel * resultLabel; @property (nonatomic, strong) UIStackView * stackView; -@property (readwrite) CHIPBasic * cluster; - @end @implementation EchoViewController @@ -44,8 +42,6 @@ - (void)viewDidLoad // listen for taps to dismiss the keyboard UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)]; [self.view addGestureRecognizer:tap]; - - self.cluster = [[CHIPBasic alloc] initWithDevice:CHIPGetPairedDevice() endpoint:0 queue:dispatch_get_main_queue()]; } - (void)dismissKeyboard @@ -110,22 +106,29 @@ - (void)updateResult:(NSString *)result - (IBAction)sendMessage:(id)sender { - if (!self.cluster) { - [self updateResult:@"Something went wrong. Cluster is not initialized."]; - } - NSString * msg = [self.messageTextField text]; if (msg.length == 0) { msg = [self.messageTextField placeholder]; } - [self updateResult:@"MfgSpecificPing command sent..."]; - - [self.cluster mfgSpecificPing:^(NSError * error, NSDictionary * values) { - NSString * resultString = (error == nil) ? @"MfgSpecificPing command: success!" - : [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code]; - [self updateResult:resultString]; - }]; + if (CHIPGetConnectedDevice(^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + CHIPBasic * cluster = [[CHIPBasic alloc] initWithDevice:chipDevice endpoint:0 queue:dispatch_get_main_queue()]; + [self updateResult:@"MfgSpecificPing command sent..."]; + + [cluster mfgSpecificPing:^(NSError * error, NSDictionary * values) { + NSString * resultString = (error == nil) ? @"MfgSpecificPing command: success!" + : [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code]; + [self updateResult:resultString]; + }]; + } else { + [self updateResult:@"Failed to establish a connection with the device"]; + } + })) { + [self updateResult:@"Waiting for connection with the device"]; + } else { + [self updateResult:@"Failed to trigger the connection with the device"]; + } } @end diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/Fabric/FabricUIViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/Fabric/FabricUIViewController.m index c6f22369660842..af6a32b8d89167 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/Fabric/FabricUIViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/Fabric/FabricUIViewController.m @@ -23,9 +23,6 @@ @interface FabricUIViewController () @property (nonatomic, strong) NSArray * fabricsList; @property (nonatomic, strong) NSNumber * fabricID; - -@property (readwrite) CHIPOperationalCredentials * cluster; - @end @implementation FabricUIViewController @@ -34,9 +31,6 @@ @implementation FabricUIViewController - (void)viewDidLoad { [super viewDidLoad]; - self.cluster = [[CHIPOperationalCredentials alloc] initWithDevice:CHIPGetPairedDevice() - endpoint:0 - queue:dispatch_get_main_queue()]; [self setupUIElements]; [self fetchFabricsList]; @@ -222,21 +216,35 @@ - (void)updateFabricsListUIWithFabrics:(NSArray *)fabricsList error:(NSError *)e - (void)fetchFabricsList { NSLog(@"Request to fetchFabricsList"); - [self updateResult:[NSString stringWithFormat:@"readAttributeFabricsList command sent."] isError:NO]; - [self.cluster readAttributeFabricsListWithResponseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { - NSArray * fabricsList = [values objectForKey:@"value"]; - if (error) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self updateResult:[NSString stringWithFormat:@"readAttributeFabricsList command failed: %@.", error] isError:YES]; - }); - } else { - dispatch_async(dispatch_get_main_queue(), ^{ - [self updateResult:[NSString stringWithFormat:@"Command readAttributeFabricsList command succeeded."] isError:NO]; - }); - } - NSLog(@"Got back fabrics list: %@ error %@", values, error); - [self updateFabricsListUIWithFabrics:fabricsList error:error]; - }]; + if (CHIPGetConnectedDevice(^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + CHIPOperationalCredentials * cluster = + [[CHIPOperationalCredentials alloc] initWithDevice:chipDevice endpoint:0 queue:dispatch_get_main_queue()]; + [self updateResult:[NSString stringWithFormat:@"readAttributeFabricsList command sent."] isError:NO]; + [cluster readAttributeFabricsListWithResponseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { + NSArray * fabricsList = [values objectForKey:@"value"]; + if (error) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateResult:[NSString stringWithFormat:@"readAttributeFabricsList command failed: %@.", error] + isError:YES]; + }); + } else { + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateResult:[NSString stringWithFormat:@"Command readAttributeFabricsList command succeeded."] + isError:NO]; + }); + } + NSLog(@"Got back fabrics list: %@ error %@", values, error); + [self updateFabricsListUIWithFabrics:fabricsList error:error]; + }]; + } else { + [self updateResult:[NSString stringWithFormat:@"Failed to establish a connection with the device"] isError:YES]; + } + })) { + [self updateResult:[NSString stringWithFormat:@"Waiting for connection with the device"] isError:NO]; + } else { + [self updateResult:[NSString stringWithFormat:@"Failed to trigger the connection with the device"] isError:YES]; + } } // MARK: UIButton methods @@ -251,20 +259,36 @@ - (IBAction)removeAllFabricsButtonPressed:(id)sender @"accessory, including this one, and put the device back in commissioning." preferredStyle:UIAlertControllerStyleAlert]; - UIAlertAction * defaultAction = - [UIAlertAction actionWithTitle:@"Remove" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { - [self.cluster removeAllFabrics:^(NSError * error, NSDictionary * values) { - BOOL errorOccured = (error != nil); - NSString * resultString = errorOccured - ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code] - : @"Remove all fabrics success"; - dispatch_async(dispatch_get_main_queue(), ^{ - [self updateResult:resultString isError:errorOccured]; - }); - }]; - }]; + UIAlertAction * defaultAction = [UIAlertAction + actionWithTitle:@"Remove" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { + if (CHIPGetConnectedDevice(^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + CHIPOperationalCredentials * cluster = + [[CHIPOperationalCredentials alloc] initWithDevice:chipDevice + endpoint:0 + queue:dispatch_get_main_queue()]; + [cluster removeAllFabrics:^(NSError * error, NSDictionary * values) { + BOOL errorOccured = (error != nil); + NSString * resultString = errorOccured + ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code] + : @"Remove all fabrics success"; + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateResult:resultString isError:errorOccured]; + }); + }]; + } else { + [self updateResult:[NSString stringWithFormat:@"Failed to establish a connection with the device"] + isError:YES]; + } + })) { + [self updateResult:[NSString stringWithFormat:@"Waiting for connection with the device"] isError:NO]; + } else { + [self updateResult:[NSString stringWithFormat:@"Failed to trigger the connection with the device"] + isError:YES]; + } + }]; UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel @@ -282,31 +306,46 @@ - (IBAction)updateFabricLabelButtonPressed:(id)sender NSString * label = _updateFabricLabelTextField.text; NSLog(@"Request to updateFabricLabel %@", label); [self.updateFabricLabelTextField resignFirstResponder]; - [self updateResult:[NSString stringWithFormat:@"updateFabricLabel command sent."] isError:NO]; - [self.cluster - updateFabricLabel:label - responseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (error) { - NSLog(@"Got back error trying to updateFabricLabel %@", error); - dispatch_async(dispatch_get_main_queue(), ^{ - self->_updateFabricLabelTextField.text = @""; - [self updateResult:[NSString stringWithFormat:@"Command updateFabricLabel failed with error %@", error] - isError:YES]; - }); - } else { - NSLog(@"Successfully updated the label: %@", values); - dispatch_async(dispatch_get_main_queue(), ^{ - self->_updateFabricLabelTextField.text = @""; - [self - updateResult:[NSString - stringWithFormat:@"Command updateFabricLabel succeeded to update label to %@", label] - isError:NO]; - [self fetchFabricsList]; - }); - } - }); - }]; + + if (CHIPGetConnectedDevice(^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + CHIPOperationalCredentials * cluster = + [[CHIPOperationalCredentials alloc] initWithDevice:chipDevice endpoint:0 queue:dispatch_get_main_queue()]; + [self updateResult:[NSString stringWithFormat:@"updateFabricLabel command sent."] isError:NO]; + [cluster + updateFabricLabel:label + responseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (error) { + NSLog(@"Got back error trying to updateFabricLabel %@", error); + dispatch_async(dispatch_get_main_queue(), ^{ + self->_updateFabricLabelTextField.text = @""; + [self + updateResult:[NSString stringWithFormat:@"Command updateFabricLabel failed with error %@", + error] + isError:YES]; + }); + } else { + NSLog(@"Successfully updated the label: %@", values); + dispatch_async(dispatch_get_main_queue(), ^{ + self->_updateFabricLabelTextField.text = @""; + [self updateResult:[NSString stringWithFormat: + @"Command updateFabricLabel succeeded to update label to %@", + label] + isError:NO]; + [self fetchFabricsList]; + }); + } + }); + }]; + } else { + [self updateResult:[NSString stringWithFormat:@"Failed to establish a connection with the device"] isError:YES]; + } + })) { + [self updateResult:[NSString stringWithFormat:@"Waiting for connection with the device"] isError:NO]; + } else { + [self updateResult:[NSString stringWithFormat:@"Failed to trigger the connection with the device"] isError:YES]; + } } - (IBAction)removeFabricButtonPressed:(id)sender @@ -319,28 +358,43 @@ - (IBAction)removeFabricButtonPressed:(id)sender NSNumber * fabricId = [fabricToRemove objectForKey:@"FabricId"]; NSNumber * nodeID = [fabricToRemove objectForKey:@"NodeId"]; NSNumber * vendorID = [fabricToRemove objectForKey:@"VendorId"]; - [self updateResult:[NSString stringWithFormat:@"removeFabric command sent for fabricID %@.", fabricId] isError:NO]; - [self.cluster removeFabric:[fabricId unsignedLongLongValue] - nodeId:[nodeID unsignedLongLongValue] - vendorId:[vendorID unsignedShortValue] - responseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { - if (error) { - NSLog(@"Failed to remove fabric with error %@", error); - dispatch_async(dispatch_get_main_queue(), ^{ - [self updateResult:[NSString stringWithFormat:@"Command removeFabric failed with error %@", error] - isError:YES]; - self->_removeFabricTextField.text = @""; - }); - } else { - NSLog(@"Succeeded removing fabric!"); - dispatch_async(dispatch_get_main_queue(), ^{ - self->_removeFabricTextField.text = @""; - [self - updateResult:[NSString stringWithFormat:@"Command removeFabric succeeded to remove %@", fabricId] - isError:NO]; - }); - } - }]; + + if (CHIPGetConnectedDevice(^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + CHIPOperationalCredentials * cluster = + [[CHIPOperationalCredentials alloc] initWithDevice:chipDevice endpoint:0 queue:dispatch_get_main_queue()]; + [self updateResult:[NSString stringWithFormat:@"removeFabric command sent for fabricID %@.", fabricId] + isError:NO]; + [cluster removeFabric:[fabricId unsignedLongLongValue] + nodeId:[nodeID unsignedLongLongValue] + vendorId:[vendorID unsignedShortValue] + responseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { + if (error) { + NSLog(@"Failed to remove fabric with error %@", error); + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateResult:[NSString + stringWithFormat:@"Command removeFabric failed with error %@", error] + isError:YES]; + self->_removeFabricTextField.text = @""; + }); + } else { + NSLog(@"Succeeded removing fabric!"); + dispatch_async(dispatch_get_main_queue(), ^{ + self->_removeFabricTextField.text = @""; + [self updateResult:[NSString stringWithFormat:@"Command removeFabric succeeded to remove %@", + fabricId] + isError:NO]; + }); + } + }]; + } else { + [self updateResult:[NSString stringWithFormat:@"Failed to establish a connection with the device"] isError:YES]; + } + })) { + [self updateResult:[NSString stringWithFormat:@"Waiting for connection with the device"] isError:NO]; + } else { + [self updateResult:[NSString stringWithFormat:@"Failed to trigger the connection with the device"] isError:YES]; + } } else { dispatch_async(dispatch_get_main_queue(), ^{ self->_removeFabricTextField.text = @""; diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/MultiAdmin/MultiAdminViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/MultiAdmin/MultiAdminViewController.m index 26a54f8c9b27ba..821baaf611a9dd 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/MultiAdmin/MultiAdminViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/MultiAdmin/MultiAdminViewController.m @@ -201,43 +201,50 @@ - (IBAction)openPairingWindow:(id)sender { uint32_t setupPIN = arc4random(); [_deviceSelector forSelectedDevices:^(uint64_t deviceId) { - CHIPDevice * chipDevice = CHIPGetPairedDeviceWithID(deviceId); - // send message - if (chipDevice != nil && [chipDevice isActive]) { - NSString * timeoutStr = [self.timeoutField text]; - if (timeoutStr.length == 0) { - timeoutStr = [self.timeoutField placeholder]; - } - int timeout = [timeoutStr intValue]; - - NSString * output; - NSError * error; - if ([self.useOnboardingTokenSwitch isOn]) { - NSString * discriminatorStr = [self.discriminatorField text]; - if (discriminatorStr.length == 0) { - discriminatorStr = [self.discriminatorField placeholder]; - } - NSInteger discriminator = [discriminatorStr intValue]; - - output = [chipDevice openPairingWindowWithPIN:timeout discriminator:discriminator setupPIN:setupPIN error:&error]; - - if (output != nil) { - NSString * result = [@"Use Manual Code: " stringByAppendingString:output]; - [self updateResult:result]; - } else { - [self updateResult:@"Failed in opening the pairing window"]; - } - } else { - BOOL didSend = [chipDevice openPairingWindow:timeout error:&error]; - if (didSend) { - [self updateResult:@"Scan the QR code on the device"]; + if (CHIPGetConnectedDeviceWithID(deviceId, ^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + NSString * timeoutStr = [self.timeoutField text]; + if (timeoutStr.length == 0) { + timeoutStr = [self.timeoutField placeholder]; + } + int timeout = [timeoutStr intValue]; + + NSString * output; + NSError * error; + if ([self.useOnboardingTokenSwitch isOn]) { + NSString * discriminatorStr = [self.discriminatorField text]; + if (discriminatorStr.length == 0) { + discriminatorStr = [self.discriminatorField placeholder]; + } + NSInteger discriminator = [discriminatorStr intValue]; + + output = [chipDevice openPairingWindowWithPIN:timeout + discriminator:discriminator + setupPIN:setupPIN + error:&error]; + + if (output != nil) { + NSString * result = [@"Use Manual Code: " stringByAppendingString:output]; + [self updateResult:result]; + } else { + [self updateResult:@"Failed in opening the pairing window"]; + } + } else { + BOOL didSend = [chipDevice openPairingWindow:timeout error:&error]; + if (didSend) { + [self updateResult:@"Scan the QR code on the device"]; + } else { + NSString * errorString = [@"Error: " stringByAppendingString:error.localizedDescription]; + [self updateResult:errorString]; + } + } } else { - NSString * errorString = [@"Error: " stringByAppendingString:error.localizedDescription]; - [self updateResult:errorString]; + [self updateResult:[NSString stringWithFormat:@"Failed to establish a connection with the device"]]; } - } + })) { + [self updateResult:[NSString stringWithFormat:@"Waiting for connection with the device"]]; } else { - [self updateResult:@"Controller not connected"]; + [self updateResult:[NSString stringWithFormat:@"Failed to trigger the connection with the device"]]; } }]; } diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/OnOffCluster/OnOffViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/OnOffCluster/OnOffViewController.m index b7f078e91cd22f..563366149759f8 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/OnOffCluster/OnOffViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/OnOffCluster/OnOffViewController.m @@ -237,16 +237,24 @@ - (IBAction)onButtonTapped:(id)sender [self updateResult:[NSString stringWithFormat:@"On command sent on endpoint %@", @(endpoint)]]; [_deviceSelector forSelectedDevices:^(uint64_t deviceId) { - CHIPDevice * chipDevice = CHIPGetPairedDeviceWithID(deviceId); - if (chipDevice != nil) { - CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice endpoint:endpoint queue:dispatch_get_main_queue()]; - [onOff on:^(NSError * error, NSDictionary * values) { - NSString * resultString - = (error != nil) ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code] : @"On command success"; - [self updateResult:resultString]; - }]; + if (CHIPGetConnectedDeviceWithID(deviceId, ^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice + endpoint:endpoint + queue:dispatch_get_main_queue()]; + [onOff on:^(NSError * error, NSDictionary * values) { + NSString * resultString = (error != nil) + ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code] + : @"On command success"; + [self updateResult:resultString]; + }]; + } else { + [self updateResult:[NSString stringWithFormat:@"Failed to establish a connection with the device"]]; + } + })) { + [self updateResult:[NSString stringWithFormat:@"Waiting for connection with the device"]]; } else { - [self updateResult:[NSString stringWithFormat:@"Device not found"]]; + [self updateResult:[NSString stringWithFormat:@"Failed to trigger the connection with the device"]]; } }]; } @@ -258,16 +266,24 @@ - (IBAction)offButtonTapped:(id)sender [self updateResult:[NSString stringWithFormat:@"Off command sent on endpoint %@", @(endpoint)]]; [_deviceSelector forSelectedDevices:^(uint64_t deviceId) { - CHIPDevice * chipDevice = CHIPGetPairedDeviceWithID(deviceId); - if (chipDevice != nil) { - CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice endpoint:endpoint queue:dispatch_get_main_queue()]; - [onOff off:^(NSError * error, NSDictionary * values) { - NSString * resultString = (error != nil) ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code] - : @"Off command success"; - [self updateResult:resultString]; - }]; + if (CHIPGetConnectedDeviceWithID(deviceId, ^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice + endpoint:endpoint + queue:dispatch_get_main_queue()]; + [onOff off:^(NSError * error, NSDictionary * values) { + NSString * resultString = (error != nil) + ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code] + : @"Off command success"; + [self updateResult:resultString]; + }]; + } else { + [self updateResult:[NSString stringWithFormat:@"Failed to establish a connection with the device"]]; + } + })) { + [self updateResult:[NSString stringWithFormat:@"Waiting for connection with the device"]]; } else { - [self updateResult:[NSString stringWithFormat:@"Device not found"]]; + [self updateResult:[NSString stringWithFormat:@"Failed to trigger the connection with the device"]]; } }]; } @@ -279,16 +295,24 @@ - (IBAction)toggleButtonTapped:(id)sender [self updateResult:[NSString stringWithFormat:@"Toggle command sent on endpoint %@", @(endpoint)]]; [_deviceSelector forSelectedDevices:^(uint64_t deviceId) { - CHIPDevice * chipDevice = CHIPGetPairedDeviceWithID(deviceId); - if (chipDevice != nil) { - CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice endpoint:endpoint queue:dispatch_get_main_queue()]; - [onOff toggle:^(NSError * error, NSDictionary * values) { - NSString * resultString = (error != nil) ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code] - : @"Toggle command success"; - [self updateResult:resultString]; - }]; + if (CHIPGetConnectedDeviceWithID(deviceId, ^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice + endpoint:endpoint + queue:dispatch_get_main_queue()]; + [onOff toggle:^(NSError * error, NSDictionary * values) { + NSString * resultString = (error != nil) + ? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code] + : @"Toggle command success"; + [self updateResult:resultString]; + }]; + } else { + [self updateResult:[NSString stringWithFormat:@"Failed to establish a connection with the device"]]; + } + })) { + [self updateResult:[NSString stringWithFormat:@"Waiting for connection with the device"]]; } else { - [self updateResult:[NSString stringWithFormat:@"Device not found"]]; + [self updateResult:[NSString stringWithFormat:@"Failed to trigger the connection with the device"]]; } }]; } diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/QRCode/QRCodeViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/QRCode/QRCodeViewController.m index 6574e7bb7a1d46..687ea8854f1fd3 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/QRCode/QRCodeViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/QRCode/QRCodeViewController.m @@ -368,21 +368,27 @@ - (void)readerSession:(nonnull NFCNDEFReaderSession *)session didInvalidateWithE - (void)setVendorIDOnAccessory { NSLog(@"Call to setVendorIDOnAccessory"); - CHIPDevice * device = CHIPGetPairedDevice(); - if (device) { - CHIPOperationalCredentials * opCreds = [[CHIPOperationalCredentials alloc] initWithDevice:device - endpoint:0 - queue:dispatch_get_main_queue()]; - [opCreds setFabric:kCHIPToolTmpVendorId - responseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { - if (error.code != CHIPSuccess) { - NSLog(@"Got back error trying to getFabricId %@", error); - } else { - NSLog(@"Got back fabricID values %@, storing it", values); - NSNumber * fabricID = [values objectForKey:@"FabricId"]; - CHIPSetDomainValueForKey(kCHIPToolDefaultsDomain, kFabricIdKey, fabricID); - } - }]; + if (CHIPGetConnectedDevice(^(CHIPDevice * _Nullable device, NSError * _Nullable error) { + if (device) { + CHIPOperationalCredentials * opCreds = + [[CHIPOperationalCredentials alloc] initWithDevice:device endpoint:0 queue:dispatch_get_main_queue()]; + [opCreds setFabric:kCHIPToolTmpVendorId + responseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { + if (error.code != CHIPSuccess) { + NSLog(@"Got back error trying to getFabricId %@", error); + } else { + NSLog(@"Got back fabricID values %@, storing it", values); + NSNumber * fabricID = [values objectForKey:@"FabricId"]; + CHIPSetDomainValueForKey(kCHIPToolDefaultsDomain, kFabricIdKey, fabricID); + } + }]; + } else { + NSLog(@"Status: Failed to establish a connection with the device"); + } + })) { + NSLog(@"Status: Waiting for connection with the device"); + } else { + NSLog(@"Status: Failed to trigger the connection with the device"); } } @@ -543,39 +549,59 @@ - (void)retrieveAndSendWifiCredentials - (void)addWiFiNetwork:(NSString *)ssid password:(NSString *)password { - self.cluster = [[CHIPNetworkCommissioning alloc] initWithDevice:CHIPGetPairedDevice() - endpoint:0 - queue:dispatch_get_main_queue()]; - NSData * networkId = [ssid dataUsingEncoding:NSUTF8StringEncoding]; - NSData * credentials = [password dataUsingEncoding:NSUTF8StringEncoding]; - uint64_t breadcrumb = 0; - uint32_t timeoutMs = 3000; - - __weak typeof(self) weakSelf = self; - [_cluster addWiFiNetwork:networkId - credentials:credentials - breadcrumb:breadcrumb - timeoutMs:timeoutMs - responseHandler:^(NSError * error, NSDictionary * values) { - [weakSelf onAddNetworkResponse:error isWiFi:YES]; - }]; + if (CHIPGetConnectedDevice(^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + self.cluster = [[CHIPNetworkCommissioning alloc] initWithDevice:chipDevice + endpoint:0 + queue:dispatch_get_main_queue()]; + NSData * networkId = [ssid dataUsingEncoding:NSUTF8StringEncoding]; + NSData * credentials = [password dataUsingEncoding:NSUTF8StringEncoding]; + uint64_t breadcrumb = 0; + uint32_t timeoutMs = 3000; + + __weak typeof(self) weakSelf = self; + [self->_cluster addWiFiNetwork:networkId + credentials:credentials + breadcrumb:breadcrumb + timeoutMs:timeoutMs + responseHandler:^(NSError * error, NSDictionary * values) { + [weakSelf onAddNetworkResponse:error isWiFi:YES]; + }]; + } else { + NSLog(@"Status: Failed to establish a connection with the device"); + } + })) { + NSLog(@"Status: Waiting for connection with the device"); + } else { + NSLog(@"Status: Failed to trigger the connection with the device"); + } } - (void)addThreadNetwork:(NSData *)threadDataSet { - self.cluster = [[CHIPNetworkCommissioning alloc] initWithDevice:CHIPGetPairedDevice() - endpoint:0 - queue:dispatch_get_main_queue()]; - uint64_t breadcrumb = 0; - uint32_t timeoutMs = 3000; - - __weak typeof(self) weakSelf = self; - [_cluster addThreadNetwork:threadDataSet - breadcrumb:breadcrumb - timeoutMs:timeoutMs - responseHandler:^(NSError * error, NSDictionary * values) { - [weakSelf onAddNetworkResponse:error isWiFi:NO]; - }]; + if (CHIPGetConnectedDevice(^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + self.cluster = [[CHIPNetworkCommissioning alloc] initWithDevice:chipDevice + endpoint:0 + queue:dispatch_get_main_queue()]; + uint64_t breadcrumb = 0; + uint32_t timeoutMs = 3000; + + __weak typeof(self) weakSelf = self; + [self->_cluster addThreadNetwork:threadDataSet + breadcrumb:breadcrumb + timeoutMs:timeoutMs + responseHandler:^(NSError * error, NSDictionary * values) { + [weakSelf onAddNetworkResponse:error isWiFi:NO]; + }]; + } else { + NSLog(@"Status: Failed to establish a connection with the device"); + } + })) { + NSLog(@"Status: Waiting for connection with the device"); + } else { + NSLog(@"Status: Failed to trigger the connection with the device"); + } } - (void)onAddNetworkResponse:(NSError *)error isWiFi:(BOOL)isWiFi diff --git a/src/darwin/CHIPTool/CHIPTool/View Controllers/Temperature Sensor/TemperatureSensorViewController.m b/src/darwin/CHIPTool/CHIPTool/View Controllers/Temperature Sensor/TemperatureSensorViewController.m index e051bcc35d37df..8f8c9ce5668bdf 100644 --- a/src/darwin/CHIPTool/CHIPTool/View Controllers/Temperature Sensor/TemperatureSensorViewController.m +++ b/src/darwin/CHIPTool/CHIPTool/View Controllers/Temperature Sensor/TemperatureSensorViewController.m @@ -16,8 +16,6 @@ @interface TemperatureSensorViewController () @property (nonatomic, strong) UITextField * maxIntervalInSecondsTextField; @property (nonatomic, strong) UITextField * deltaInFahrenheitTextField; @property (nonatomic, strong) UIButton * sendReportingSetup; - -@property (nonatomic, strong) CHIPTemperatureMeasurement * cluster; @end @implementation TemperatureSensorViewController @@ -32,9 +30,6 @@ - (void)viewDidLoad UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)]; [self.view addGestureRecognizer:tap]; - self.cluster = [[CHIPTemperatureMeasurement alloc] initWithDevice:CHIPGetPairedDevice() - endpoint:1 - queue:dispatch_get_main_queue()]; [self readCurrentTemperature]; } @@ -166,12 +161,26 @@ - (void)updateTempInUI:(int)newTemp - (void)readCurrentTemperature { - [self.cluster readAttributeMeasuredValueWithResponseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { - if (error != nil) - return; - NSNumber * value = values[@"value"]; - [self updateTempInUI:value.shortValue]; - }]; + if (CHIPGetConnectedDevice(^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + CHIPTemperatureMeasurement * cluster = + [[CHIPTemperatureMeasurement alloc] initWithDevice:chipDevice endpoint:1 queue:dispatch_get_main_queue()]; + + [cluster + readAttributeMeasuredValueWithResponseHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) { + if (error != nil) + return; + NSNumber * value = values[@"value"]; + [self updateTempInUI:value.shortValue]; + }]; + } else { + NSLog(@"Status: Failed to establish a connection with the device"); + } + })) { + NSLog(@"Status: Waiting for connection with the device"); + } else { + NSLog(@"Status: Failed to trigger the connection with the device"); + } } - (void)reportFromUserEnteredSettings @@ -183,22 +192,36 @@ - (void)reportFromUserEnteredSettings NSLog(@"Sending temp reporting values: min %@ max %@ value %@", @(minIntervalSeconds), @(maxIntervalSeconds), @(deltaInFahrenheit)); - [self.cluster configureAttributeMeasuredValueWithMinInterval:minIntervalSeconds - maxInterval:maxIntervalSeconds - change:deltaInFahrenheit - responseHandler:^(NSError * error, NSDictionary * values) { - if (error == nil) - return; - NSLog(@"Status: update reportAttributeMeasuredValue completed with error %@", - [error description]); - }]; - - [self.cluster reportAttributeMeasuredValueWithResponseHandler:^(NSError * error, NSDictionary * values) { - if (error != nil) - return; - NSNumber * value = values[@"value"]; - [self updateTempInUI:value.shortValue]; - }]; + if (CHIPGetConnectedDevice(^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + if (chipDevice) { + CHIPTemperatureMeasurement * cluster = + [[CHIPTemperatureMeasurement alloc] initWithDevice:chipDevice endpoint:1 queue:dispatch_get_main_queue()]; + + [cluster + configureAttributeMeasuredValueWithMinInterval:minIntervalSeconds + maxInterval:maxIntervalSeconds + change:deltaInFahrenheit + responseHandler:^(NSError * error, NSDictionary * values) { + if (error == nil) + return; + NSLog(@"Status: update reportAttributeMeasuredValue completed with error %@", + [error description]); + }]; + + [cluster reportAttributeMeasuredValueWithResponseHandler:^(NSError * error, NSDictionary * values) { + if (error != nil) + return; + NSNumber * value = values[@"value"]; + [self updateTempInUI:value.shortValue]; + }]; + } else { + NSLog(@"Status: Failed to establish a connection with the device"); + } + })) { + NSLog(@"Status: Waiting for connection with the device"); + } else { + NSLog(@"Status: Failed to trigger the connection with the device"); + } } @end diff --git a/src/darwin/Framework/CHIP.xcodeproj/project.pbxproj b/src/darwin/Framework/CHIP.xcodeproj/project.pbxproj index aecf3254135c84..762c1ea59e84d6 100644 --- a/src/darwin/Framework/CHIP.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/CHIP.xcodeproj/project.pbxproj @@ -41,6 +41,8 @@ 2C222AD1255C620600E446B9 /* CHIPDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2C222ACF255C620600E446B9 /* CHIPDevice.mm */; }; 2C222ADF255C811800E446B9 /* CHIPDevice_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C222ADE255C811800E446B9 /* CHIPDevice_Internal.h */; }; 2C4DF09E248B2C60009307CB /* libmbedtls.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C4DF09D248B2C60009307CB /* libmbedtls.a */; settings = {ATTRIBUTES = (Required, ); }; }; + 2C5EEEF6268A85C400CAE3D3 /* CHIPDeviceConnectionBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C5EEEF4268A85C400CAE3D3 /* CHIPDeviceConnectionBridge.h */; }; + 2C5EEEF7268A85C400CAE3D3 /* CHIPDeviceConnectionBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2C5EEEF5268A85C400CAE3D3 /* CHIPDeviceConnectionBridge.mm */; }; 2C8C8FC0253E0C2100797F05 /* CHIPPersistentStorageDelegateBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C8C8FBD253E0C2100797F05 /* CHIPPersistentStorageDelegateBridge.h */; }; 2C8C8FC1253E0C2100797F05 /* CHIPPersistentStorageDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C8C8FBE253E0C2100797F05 /* CHIPPersistentStorageDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2C8C8FC2253E0C2100797F05 /* CHIPPersistentStorageDelegateBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2C8C8FBF253E0C2100797F05 /* CHIPPersistentStorageDelegateBridge.mm */; }; @@ -113,6 +115,8 @@ 2C222ACF255C620600E446B9 /* CHIPDevice.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CHIPDevice.mm; sourceTree = ""; }; 2C222ADE255C811800E446B9 /* CHIPDevice_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHIPDevice_Internal.h; sourceTree = ""; }; 2C4DF09D248B2C60009307CB /* libmbedtls.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmbedtls.a; path = lib/libmbedtls.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 2C5EEEF4268A85C400CAE3D3 /* CHIPDeviceConnectionBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHIPDeviceConnectionBridge.h; sourceTree = ""; }; + 2C5EEEF5268A85C400CAE3D3 /* CHIPDeviceConnectionBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CHIPDeviceConnectionBridge.mm; sourceTree = ""; }; 2C8C8FBD253E0C2100797F05 /* CHIPPersistentStorageDelegateBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHIPPersistentStorageDelegateBridge.h; sourceTree = ""; }; 2C8C8FBE253E0C2100797F05 /* CHIPPersistentStorageDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CHIPPersistentStorageDelegate.h; sourceTree = ""; }; 2C8C8FBF253E0C2100797F05 /* CHIPPersistentStorageDelegateBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CHIPPersistentStorageDelegateBridge.mm; sourceTree = ""; }; @@ -229,6 +233,8 @@ B202528F2459E34F00F97062 /* CHIP */ = { isa = PBXGroup; children = ( + 2C5EEEF4268A85C400CAE3D3 /* CHIPDeviceConnectionBridge.h */, + 2C5EEEF5268A85C400CAE3D3 /* CHIPDeviceConnectionBridge.mm */, 1E857311265519DE0050A4D9 /* CHIPApp */, 2C1B02792641DB4E00780EF1 /* CHIPOperationalCredentialsDelegate.h */, 2C1B02782641DB4E00780EF1 /* CHIPOperationalCredentialsDelegate.mm */, @@ -302,6 +308,7 @@ 2C8C8FC1253E0C2100797F05 /* CHIPPersistentStorageDelegate.h in Headers */, B2E0D7B5245B0B5C003C5B48 /* CHIPQRCodeSetupPayloadParser.h in Headers */, 1EC4CE6425CC276600D7304F /* CHIPClustersObjc.h in Headers */, + 2C5EEEF6268A85C400CAE3D3 /* CHIPDeviceConnectionBridge.h in Headers */, 2C8C8FC0253E0C2100797F05 /* CHIPPersistentStorageDelegateBridge.h in Headers */, 2C222ADF255C811800E446B9 /* CHIPDevice_Internal.h in Headers */, 991DC08B247704DC00C13860 /* CHIPLogging.h in Headers */, @@ -435,6 +442,7 @@ 1E85730E265519AE0050A4D9 /* CHIPClusters.cpp in Sources */, 1E85732326551A490050A4D9 /* process-global-message.cpp in Sources */, 1E85732E26551A490050A4D9 /* ember-print.cpp in Sources */, + 2C5EEEF7268A85C400CAE3D3 /* CHIPDeviceConnectionBridge.mm in Sources */, 2C222AD1255C620600E446B9 /* CHIPDevice.mm in Sources */, 1E857306265519720050A4D9 /* CHIPClientCallbacks.cpp in Sources */, 1E85733726551AAE0050A4D9 /* encoder.cpp in Sources */, diff --git a/src/darwin/Framework/CHIP/CHIPDeviceConnectionBridge.h b/src/darwin/Framework/CHIP/CHIPDeviceConnectionBridge.h new file mode 100644 index 00000000000000..6ddc5a81476b5b --- /dev/null +++ b/src/darwin/Framework/CHIP/CHIPDeviceConnectionBridge.h @@ -0,0 +1,55 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import + +#include +#include + +NS_ASSUME_NONNULL_BEGIN + +class CHIPDeviceConnectionBridge : public chip::ReferenceCounted +{ +public: + CHIPDeviceConnectionBridge(CHIPDeviceConnectionCallback completionHandler, dispatch_queue_t queue) : + mCompletionHandler(completionHandler), mQueue(queue), mOnConnected(OnConnected, this), + mOnConnectFailed(OnConnectionFailure, this) + {} + + ~CHIPDeviceConnectionBridge() + { + mOnConnected.Cancel(); + mOnConnectFailed.Cancel(); + } + + CHIP_ERROR connect(chip::Controller::DeviceController * controller, chip::NodeId deviceID) + { + return controller->GetConnectedDevice(deviceID, &mOnConnected, &mOnConnectFailed); + } + +private: + CHIPDeviceConnectionCallback mCompletionHandler; + dispatch_queue_t mQueue; + chip::Callback::Callback mOnConnected; + chip::Callback::Callback mOnConnectFailed; + + static void OnConnected(void * context, chip::Controller::Device * device); + static void OnConnectionFailure(void * context, chip::NodeId deviceId, CHIP_ERROR error); +}; + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/CHIPDeviceConnectionBridge.mm b/src/darwin/Framework/CHIP/CHIPDeviceConnectionBridge.mm new file mode 100644 index 00000000000000..0271293f9a93f0 --- /dev/null +++ b/src/darwin/Framework/CHIP/CHIPDeviceConnectionBridge.mm @@ -0,0 +1,39 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "CHIPDeviceConnectionBridge.h" +#import "CHIPDevice_Internal.h" +#import "CHIPError.h" + +void CHIPDeviceConnectionBridge::OnConnected(void * context, chip::Controller::Device * device) +{ + auto * object = static_cast(context); + CHIPDevice * chipDevice = [[CHIPDevice alloc] initWithDevice:device]; + dispatch_async(object->mQueue, ^{ + object->mCompletionHandler(chipDevice, nil); + object->Release(); + }); +} + +void CHIPDeviceConnectionBridge::OnConnectionFailure(void * context, chip::NodeId deviceId, CHIP_ERROR error) +{ + auto * object = static_cast(context); + dispatch_async(object->mQueue, ^{ + object->mCompletionHandler(nil, [CHIPError errorForCHIPErrorCode:error]); + object->Release(); + }); +} diff --git a/src/darwin/Framework/CHIP/CHIPDeviceController.h b/src/darwin/Framework/CHIP/CHIPDeviceController.h index 6b03a831403345..7bc3db3bc310f0 100644 --- a/src/darwin/Framework/CHIP/CHIPDeviceController.h +++ b/src/darwin/Framework/CHIP/CHIPDeviceController.h @@ -26,6 +26,8 @@ NS_ASSUME_NONNULL_BEGIN +typedef void (^CHIPDeviceConnectionCallback)(CHIPDevice * _Nullable device, NSError * _Nullable error); + @protocol CHIPDevicePairingDelegate; @protocol CHIPPersistentStorageDelegate; @@ -61,6 +63,11 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)stopDevicePairing:(uint64_t)deviceID error:(NSError * __autoreleasing *)error; - (void)updateDevice:(uint64_t)deviceID fabricId:(uint64_t)fabricId; +- (BOOL)isDevicePaired:(uint64_t)deviceID error:(NSError * __autoreleasing *)error; +- (BOOL)getConnectedDevice:(uint64_t)deviceID + completionHandler:(CHIPDeviceConnectionCallback)completionHandler + queue:(dispatch_queue_t)queue + error:(NSError * __autoreleasing *)error; - (nullable CHIPDevice *)getPairedDevice:(uint64_t)deviceID error:(NSError * __autoreleasing *)error; - (instancetype)init NS_UNAVAILABLE; diff --git a/src/darwin/Framework/CHIP/CHIPDeviceController.mm b/src/darwin/Framework/CHIP/CHIPDeviceController.mm index cf3e52e28988bb..1b60a62b1ba9a2 100644 --- a/src/darwin/Framework/CHIP/CHIPDeviceController.mm +++ b/src/darwin/Framework/CHIP/CHIPDeviceController.mm @@ -25,6 +25,8 @@ #import "CHIPSetupPayload.h" #import "gen/CHIPClustersObjc.h" +#import "CHIPDeviceConnectionBridge.h" + #include #include @@ -355,6 +357,47 @@ - (BOOL)stopDevicePairing:(uint64_t)deviceID error:(NSError * __autoreleasing *) return success; } +- (BOOL)isDevicePaired:(uint64_t)deviceID error:(NSError * __autoreleasing *)error +{ + __block BOOL paired = NO; + if (![self isRunning]) { + [self checkForError:CHIP_ERROR_INCORRECT_STATE logMsg:kErrorNotRunning error:error]; + return paired; + } + dispatch_sync(_chipWorkQueue, ^{ + if ([self isRunning]) { + paired = self.cppCommissioner->DoesDevicePairingExist(chip::PeerId().SetNodeId(deviceID)); + } + }); + + return paired; +} + +- (BOOL)getConnectedDevice:(uint64_t)deviceID + completionHandler:(CHIPDeviceConnectionCallback)completionHandler + queue:(dispatch_queue_t)queue + error:(NSError * __autoreleasing *)error +{ + __block CHIP_ERROR errorCode = CHIP_ERROR_INCORRECT_STATE; + if (![self isRunning]) { + [self checkForError:errorCode logMsg:kErrorNotRunning error:error]; + return NO; + } + + dispatch_async(_chipWorkQueue, ^{ + CHIPDeviceConnectionBridge * connectionBridge = new CHIPDeviceConnectionBridge(completionHandler, queue); + errorCode = connectionBridge->connect(self->_cppCommissioner, deviceID); + + if ([self checkForError:errorCode logMsg:kErrorGetPairedDevice error:error]) { + // Errors are propagated to the caller thru completionHandler. + // No extra error handling is needed here. + return; + } + }); + + return YES; +} + - (CHIPDevice *)getPairedDevice:(uint64_t)deviceID error:(NSError * __autoreleasing *)error { __block CHIPDevice * chipDevice = nil; diff --git a/src/darwin/Framework/CHIPTests/CHIPControllerTests.m b/src/darwin/Framework/CHIPTests/CHIPControllerTests.m index 23f6ad9d6d9874..21803b0cca42f7 100644 --- a/src/darwin/Framework/CHIPTests/CHIPControllerTests.m +++ b/src/darwin/Framework/CHIPTests/CHIPControllerTests.m @@ -63,7 +63,11 @@ - (void)testControllerInvalidAccess CHIPDeviceController * controller = [CHIPDeviceController sharedController]; NSError * error; XCTAssertFalse([controller isRunning]); - XCTAssertNil([controller getPairedDevice:1234 error:&error]); + XCTAssertFalse([controller getConnectedDevice:1234 + completionHandler:^(CHIPDevice * _Nullable chipDevice, NSError * _Nullable error) { + } + queue:dispatch_get_main_queue() + error:&error]); XCTAssertEqual(error.code, CHIPErrorCodeInvalidState); XCTAssertFalse([controller unpairDevice:1 error:&error]); XCTAssertEqual(error.code, CHIPErrorCodeInvalidState);