Skip to content

Commit

Permalink
Fix attribute reads on Darwin to support all Matter types (#12146)
Browse files Browse the repository at this point in the history
* Improve signatures of Darwin completion handlers for commands.

The NSError argument should be last, and the data should be the response params struct.

* Improve signatures of Darwin completion handlers for attribute reads and writes.

For reads, the NSError argument should be last and the data should be the actual data value.

For writes, there should just be an NSError argument.

* Change Darwin attribute reads to use new read API.

This handles nullables.
  • Loading branch information
bzbarsky-apple authored and pull[bot] committed Jun 20, 2023
1 parent 38508e0 commit 28a4c9b
Show file tree
Hide file tree
Showing 32 changed files with 34,960 additions and 20,959 deletions.
729 changes: 729 additions & 0 deletions src/app/tests/suites/TestCluster.yaml

Large diffs are not rendered by default.

729 changes: 0 additions & 729 deletions src/app/tests/suites/TestClusterComplexTypes.yaml

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions src/app/util/im-client-callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <app-common/zap-generated/af-structs.h>
#include <app/Command.h>
#include <app/InteractionModelEngine.h>
#include <app/data-model/Nullable.h>
#include <app/util/af-enums.h>
#include <inttypes.h>
#include <lib/support/FunctionTraits.h>
Expand All @@ -40,15 +41,26 @@ void LogStatus(uint8_t status);
typedef void (*DefaultSuccessCallback)(void * context);
typedef void (*DefaultFailureCallback)(void * context, uint8_t status);
typedef void (*BooleanAttributeCallback)(void * context, bool value);
typedef void (*NullableBooleanAttributeCallback)(void * context, const chip::app::DataModel::Nullable<bool> & value);
typedef void (*Int8uAttributeCallback)(void * context, uint8_t value);
typedef void (*NullableInt8uAttributeCallback)(void * context, const chip::app::DataModel::Nullable<uint8_t> & value);
typedef void (*Int8sAttributeCallback)(void * context, int8_t value);
typedef void (*NullableInt8sAttributeCallback)(void * context, const chip::app::DataModel::Nullable<int8_t> & value);
typedef void (*Int16uAttributeCallback)(void * context, uint16_t value);
typedef void (*NullableInt16uAttributeCallback)(void * context, const chip::app::DataModel::Nullable<uint16_t> & value);
typedef void (*Int16sAttributeCallback)(void * context, int16_t value);
typedef void (*NullableInt16sAttributeCallback)(void * context, const chip::app::DataModel::Nullable<int16_t> & value);
typedef void (*Int32uAttributeCallback)(void * context, uint32_t value);
typedef void (*NullableInt32uAttributeCallback)(void * context, const chip::app::DataModel::Nullable<uint32_t> & value);
typedef void (*Int32sAttributeCallback)(void * context, int32_t value);
typedef void (*NullableInt32sAttributeCallback)(void * context, const chip::app::DataModel::Nullable<int32_t> & value);
typedef void (*Int64uAttributeCallback)(void * context, uint64_t value);
typedef void (*NullableInt64uAttributeCallback)(void * context, const chip::app::DataModel::Nullable<uint64_t> & value);
typedef void (*Int64sAttributeCallback)(void * context, int64_t value);
typedef void (*NullableInt64sAttributeCallback)(void * context, const chip::app::DataModel::Nullable<int64_t> & value);
typedef void (*OctetStringAttributeCallback)(void * context, const chip::ByteSpan value);
typedef void (*NullableOctetStringAttributeCallback)(void * context, const chip::app::DataModel::Nullable<chip::ByteSpan> & value);
typedef void (*CharStringAttributeCallback)(void * context, const chip::CharSpan value);
typedef void (*NullableCharStringAttributeCallback)(void * context, const chip::app::DataModel::Nullable<chip::CharSpan> & value);
typedef void (*AttributeResponseFilter)(chip::TLV::TLVReader * data, chip::Callback::Cancelable * onSuccess,
chip::Callback::Cancelable * onFailure);
17 changes: 15 additions & 2 deletions src/app/zap-templates/common/ClusterTestGeneration.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,24 @@ function chip_tests_pics(options)
return templateUtil.collectBlocks(PICS.getAll(), options, this);
}

function chip_tests(list, options)
async function chip_tests(list, options)
{
const items = Array.isArray(list) ? list : list.split(',');
const names = items.map(name => name.trim());
const tests = names.map(item => parse(item));
let tests = names.map(item => parse(item));
tests = await Promise.all(tests.map(async function(test) {
test.tests = await Promise.all(test.tests.map(async function(item) {
if (item.isCommand) {
let command = await assertCommandOrAttribute(item);
item.commandObject = command;
} else if (item.isAttribute) {
let attr = await assertCommandOrAttribute(item);
item.attributeObject = attr;
}
return item;
}));
return test;
}));
return templateUtil.collectBlocks(tests, options, this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ - (IBAction)bind:(id)sender
params.endpointId = @(endpointId);
params.clusterId = @(clusterId);
[cluster bindWithParams:params
completionHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) {
completionHandler:^(NSError * _Nullable error) {
NSString * resultString = (error == nil)
? @"Bind command: success!"
: [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code];
Expand Down Expand Up @@ -177,7 +177,7 @@ - (IBAction)unbind:(id)sender
params.endpointId = @(endpointId);
params.clusterId = @(clusterId);
[cluster unbindWithParams:params
completionHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) {
completionHandler:^(NSError * _Nullable error) {
NSString * resultString = (error == nil)
? @"Unbind command: success!"
: [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ - (IBAction)sendMessage:(id)sender
CHIPBasic * cluster = [[CHIPBasic alloc] initWithDevice:chipDevice endpoint:0 queue:dispatch_get_main_queue()];
[self updateResult:@"MfgSpecificPing command sent..."];

[cluster mfgSpecificPingWithCompletionHandler:^(NSError * error, NSDictionary * values) {
[cluster mfgSpecificPingWithCompletionHandler:^(NSError * _Nullable error) {
NSString * resultString = (error == nil) ? @"MfgSpecificPing command: success!"
: [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code];
[self updateResult:resultString];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ - (void)fetchCommissionedFabricsNumber
CHIPOperationalCredentials * cluster =
[[CHIPOperationalCredentials alloc] initWithDevice:chipDevice endpoint:0 queue:dispatch_get_main_queue()];
[self updateResult:[NSString stringWithFormat:@"readAttributeFabricsList command sent."] isError:NO];
[cluster readAttributeCommissionedFabricsWithResponseHandler:^(
NSError * _Nullable error, NSDictionary * _Nullable values) {
[cluster readAttributeCommissionedFabricsWithCompletionHandler:^(
NSNumber * _Nullable commissionedFabrics, NSError * _Nullable error) {
if (error) {
dispatch_async(dispatch_get_main_queue(), ^{
[self updateResult:[NSString
Expand All @@ -244,7 +244,6 @@ - (void)fetchCommissionedFabricsNumber
[self updateResult:[NSString
stringWithFormat:@"Command readAttributeCommissionedFabrics command succeeded."]
isError:NO];
NSNumber * commissionedFabrics = [values objectForKey:@"value"];
NSString * stringResult =
[NSString stringWithFormat:@"# commissioned fabrics: %@", commissionedFabrics];
self->_commissionedFabricsLabel.text = stringResult;
Expand All @@ -270,8 +269,8 @@ - (void)fetchFabricsList
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"];
[cluster readAttributeFabricsListWithCompletionHandler:^(
NSArray * _Nullable fabricsList, NSError * _Nullable error) {
if (error) {
dispatch_async(dispatch_get_main_queue(), ^{
[self updateResult:[NSString stringWithFormat:@"readAttributeFabricsList command failed: %@.", error]
Expand All @@ -283,7 +282,7 @@ - (void)fetchFabricsList
isError:NO];
});
}
NSLog(@"Got back fabrics list: %@ error %@", values, error);
NSLog(@"Got back fabrics list: %@ error %@", fabricsList, error);
[self updateFabricsListUIWithFabrics:fabricsList error:error];
}];
} else {
Expand Down Expand Up @@ -353,7 +352,12 @@ - (IBAction)updateFabricLabelButtonPressed:(id)sender

[cluster
updateFabricLabelWithParams:params
completionHandler:^(NSError * _Nullable error, NSDictionary * _Nullable values) {
completionHandler:^(CHIPOperationalCredentialsClusterNOCResponseParams * _Nullable response,
NSError * _Nullable error) {
// TODO: UpdateFabricLabel can return errors
// via the NOCResponse response, but that
// seems like a spec bug that should be fixed
// in the spec.
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"Got back error trying to updateFabricLabel %@", error);
Expand All @@ -365,7 +369,7 @@ - (IBAction)updateFabricLabelButtonPressed:(id)sender
isError:YES];
});
} else {
NSLog(@"Successfully updated the label: %@", values);
NSLog(@"Successfully updated the label: %@", response);
dispatch_async(dispatch_get_main_queue(), ^{
self->_updateFabricLabelTextField.text = @"";
[self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ - (IBAction)onButtonTapped:(id)sender
CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice
endpoint:endpoint
queue:dispatch_get_main_queue()];
[onOff onWithCompletionHandler:^(NSError * error, NSDictionary * values) {
[onOff onWithCompletionHandler:^(NSError * error) {
NSString * resultString = (error != nil)
? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code]
: @"On command success";
Expand Down Expand Up @@ -271,7 +271,7 @@ - (IBAction)offButtonTapped:(id)sender
CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice
endpoint:endpoint
queue:dispatch_get_main_queue()];
[onOff offWithCompletionHandler:^(NSError * error, NSDictionary * values) {
[onOff offWithCompletionHandler:^(NSError * error) {
NSString * resultString = (error != nil)
? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code]
: @"Off command success";
Expand Down Expand Up @@ -300,7 +300,7 @@ - (IBAction)toggleButtonTapped:(id)sender
CHIPOnOff * onOff = [[CHIPOnOff alloc] initWithDevice:chipDevice
endpoint:endpoint
queue:dispatch_get_main_queue()];
[onOff toggleWithCompletionHandler:^(NSError * error, NSDictionary * values) {
[onOff toggleWithCompletionHandler:^(NSError * error) {
NSString * resultString = (error != nil)
? [NSString stringWithFormat:@"An error occured: 0x%02lx", error.code]
: @"Toggle command success";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -548,10 +548,15 @@ - (void)addWiFiNetwork:(NSString *)ssid password:(NSString *)password
params.timeoutMs = @(3000);

__weak typeof(self) weakSelf = self;
[self->_cluster addWiFiNetworkWithParams:params
completionHandler:^(NSError * error, NSDictionary * values) {
[weakSelf onAddNetworkResponse:error isWiFi:YES];
}];
[self->_cluster
addWiFiNetworkWithParams:params
completionHandler:^(CHIPNetworkCommissioningClusterAddWiFiNetworkResponseParams * _Nullable response,
NSError * _Nullable error) {
// TODO: addWiFiNetworkWithParams
// returns status in its response,
// not via the NSError!
[weakSelf onAddNetworkResponse:error isWiFi:YES];
}];
} else {
NSLog(@"Status: Failed to establish a connection with the device");
}
Expand All @@ -575,10 +580,15 @@ - (void)addThreadNetwork:(NSData *)threadDataSet
params.timeoutMs = @(3000);

__weak typeof(self) weakSelf = self;
[self->_cluster addThreadNetworkWithParams:params
completionHandler:^(NSError * error, NSDictionary * values) {
[weakSelf onAddNetworkResponse:error isWiFi:NO];
}];
[self->_cluster
addThreadNetworkWithParams:params
completionHandler:^(CHIPNetworkCommissioningClusterAddThreadNetworkResponseParams * _Nullable response,
NSError * _Nullable error) {
// TODO: addThreadNetworkWithParams
// returns status in its response,
// not via the NSError!
[weakSelf onAddNetworkResponse:error isWiFi:NO];
}];
} else {
NSLog(@"Status: Failed to establish a connection with the device");
}
Expand Down Expand Up @@ -609,7 +619,10 @@ - (void)onAddNetworkResponse:(NSError *)error isWiFi:(BOOL)isWiFi

__weak typeof(self) weakSelf = self;
[_cluster enableNetworkWithParams:params
completionHandler:^(NSError * err, NSDictionary * values) {
completionHandler:^(
CHIPNetworkCommissioningClusterEnableNetworkResponseParams * _Nullable response, NSError * _Nullable err) {
// TODO: enableNetworkWithParams returns status in its
// response, not via the NSError!
[weakSelf onEnableNetworkResponse:err];
}];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,11 @@ - (void)readCurrentTemperature
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];
}];
[cluster readAttributeMeasuredValueWithCompletionHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) {
if (error != nil)
return;
[self updateTempInUI:value.shortValue];
}];
} else {
NSLog(@"Status: Failed to establish a connection with the device");
}
Expand Down
Loading

0 comments on commit 28a4c9b

Please sign in to comment.