Skip to content

Commit e2ffa2d

Browse files
authored
[darwin-framework-tool] Add an optional -use-mtr-device argument to read-by-id and write-by-id commands (project-chip#36243)
* [darwin-framework-tool][use-mtr-device] Add an option to send command using an MTRDevice instead of a MTRBaseDevice * [darwin-framework-tool][use-mtr-device] Add an implementation for reading attributes via an MTRDevice * [darwin-framework-tool][use-mtr-device] Add an implementation for writing attributes via an MTRDevice
1 parent 4b83b04 commit e2ffa2d

7 files changed

+115
-7
lines changed

examples/darwin-framework-tool/commands/clusters/ClusterCommandBridge.h

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class ClusterCommand : public ModelCommand {
4545

4646
~ClusterCommand() {}
4747

48+
using ModelCommand::SendCommand;
49+
4850
CHIP_ERROR SendCommand(MTRBaseDevice * _Nonnull device, chip::EndpointId endpointId) override
4951
{
5052
id commandFields;

examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.h

+4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ class ModelCommand : public CHIPCommandBridge
5252
}
5353

5454
virtual CHIP_ERROR SendCommand(MTRBaseDevice * _Nonnull device, chip::EndpointId endPointId) = 0;
55+
virtual CHIP_ERROR SendCommand(MTRDevice * _Nonnull device, chip::EndpointId endPointId) { return CHIP_ERROR_NOT_IMPLEMENTED; }
56+
57+
protected:
58+
chip::Optional<bool> mUseMTRDevice;
5559

5660
private:
5761
chip::NodeId mNodeId;

examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.mm

+11-3
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,18 @@
2626
CHIP_ERROR ModelCommand::RunCommand()
2727
{
2828
ChipLogProgress(chipTool, "Sending command to node 0x" ChipLogFormatX64, ChipLogValueX64(mNodeId));
29-
auto * device = BaseDeviceWithNodeId(mNodeId);
30-
VerifyOrReturnError(device != nil, CHIP_ERROR_INCORRECT_STATE);
3129

32-
CHIP_ERROR err = SendCommand(device, mEndPointId);
30+
CHIP_ERROR err = CHIP_NO_ERROR;
31+
32+
if (mUseMTRDevice.ValueOr(false)) {
33+
auto * device = DeviceWithNodeId(mNodeId);
34+
VerifyOrReturnError(device != nil, CHIP_ERROR_INCORRECT_STATE);
35+
err = SendCommand(device, mEndPointId);
36+
} else {
37+
auto * device = BaseDeviceWithNodeId(mNodeId);
38+
VerifyOrReturnError(device != nil, CHIP_ERROR_INCORRECT_STATE);
39+
err = SendCommand(device, mEndPointId);
40+
}
3341

3442
if (err != CHIP_NO_ERROR) {
3543
ChipLogError(chipTool, "Error: %s", chip::ErrorStr(err));

examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h

+41-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class ReadAttribute : public ModelCommand {
2828
AddArgument("cluster-id", 0, UINT32_MAX, &mClusterId);
2929
AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeId);
3030
AddArgument("fabric-filtered", 0, 1, &mFabricFiltered);
31-
ModelCommand::AddArguments();
31+
AddCommonByIdArguments();
3232
}
3333

3434
ReadAttribute(chip::ClusterId clusterId)
@@ -37,7 +37,7 @@ class ReadAttribute : public ModelCommand {
3737
{
3838
AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeId);
3939
AddArgument("fabric-filtered", 0, 1, &mFabricFiltered);
40-
ModelCommand::AddArguments();
40+
AddCommonByIdArguments();
4141
}
4242

4343
ReadAttribute(const char * _Nonnull attributeName)
@@ -83,7 +83,46 @@ class ReadAttribute : public ModelCommand {
8383
return CHIP_NO_ERROR;
8484
}
8585

86+
CHIP_ERROR SendCommand(MTRDevice * _Nonnull device, chip::EndpointId endpointId) override
87+
{
88+
MTRReadParams * params = [[MTRReadParams alloc] init];
89+
if (mFabricFiltered.HasValue()) {
90+
params.filterByFabric = mFabricFiltered.Value();
91+
}
92+
93+
__auto_type * endpoint = @(endpointId);
94+
__auto_type * cluster = @(mClusterId);
95+
__auto_type * attribute = @(mAttributeId);
96+
__auto_type values = [device readAttributeWithEndpointID:endpoint
97+
clusterID:cluster
98+
attributeID:attribute
99+
params:params];
100+
101+
NSError * error = nil;
102+
if (nil == values) {
103+
__auto_type * userInfo = @ { @"reason" : @"No value available." };
104+
error = [NSError errorWithDomain:@"Error" code:0 userInfo:userInfo];
105+
LogNSError("Error reading attribute", error);
106+
RemoteDataModelLogger::LogAttributeErrorAsJSON(endpoint, cluster, attribute, error);
107+
} else {
108+
for (id item in values) {
109+
NSLog(@"Response Item: %@", [item description]);
110+
}
111+
RemoteDataModelLogger::LogAttributeAsJSON(endpoint, cluster, attribute, values);
112+
}
113+
114+
SetCommandExitStatus(error);
115+
return CHIP_NO_ERROR;
116+
}
117+
86118
protected:
119+
void AddCommonByIdArguments()
120+
{
121+
AddArgument("use-mtr-device", 0, 1, &mUseMTRDevice,
122+
"Use MTRDevice instead of MTRBaseDevice to send this command. Default is false.");
123+
ModelCommand::AddArguments();
124+
}
125+
87126
chip::Optional<bool> mFabricFiltered;
88127

89128
private:

examples/darwin-framework-tool/commands/clusters/WriteAttributeCommandBridge.h

+42-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#import "MTRError_Utils.h"
2626
#import <Matter/Matter.h>
2727

28+
constexpr uint32_t kDefaultExpectedValueInterval = 60000;
29+
2830
class WriteAttribute : public ModelCommand {
2931
public:
3032
WriteAttribute()
@@ -33,7 +35,7 @@ class WriteAttribute : public ModelCommand {
3335
AddArgument("cluster-id", 0, UINT32_MAX, &mClusterId);
3436
AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeId);
3537
AddArgument("attribute-value", &mAttributeValue);
36-
AddArguments();
38+
AddCommonByIdArguments();
3739
}
3840

3941
WriteAttribute(chip::ClusterId clusterId)
@@ -42,7 +44,7 @@ class WriteAttribute : public ModelCommand {
4244
{
4345
AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeId);
4446
AddArgument("attribute-value", &mAttributeValue);
45-
AddArguments();
47+
AddCommonByIdArguments();
4648
}
4749

4850
~WriteAttribute() {}
@@ -54,6 +56,13 @@ class WriteAttribute : public ModelCommand {
5456
return WriteAttribute::SendCommand(device, endpointId, mClusterId, mAttributeId, value);
5557
}
5658

59+
CHIP_ERROR SendCommand(MTRDevice * _Nonnull device, chip::EndpointId endpointId) override
60+
{
61+
id value;
62+
ReturnErrorOnFailure(GetValue(&value));
63+
return WriteAttribute::SendCommand(device, endpointId, mClusterId, mAttributeId, value);
64+
}
65+
5766
CHIP_ERROR SendCommand(MTRBaseDevice * _Nonnull device, chip::EndpointId endpointId, chip::ClusterId clusterId,
5867
chip::AttributeId attributeId, id _Nonnull value)
5968
{
@@ -87,6 +96,28 @@ class WriteAttribute : public ModelCommand {
8796
return CHIP_NO_ERROR;
8897
}
8998

99+
CHIP_ERROR SendCommand(MTRDevice * _Nonnull device, chip::EndpointId endpointId, chip::ClusterId clusterId,
100+
chip::AttributeId attributeId, id _Nonnull value)
101+
{
102+
__auto_type * endpoint = @(endpointId);
103+
__auto_type * cluster = @(mClusterId);
104+
__auto_type * attribute = @(mAttributeId);
105+
__auto_type * expectedValueInterval = @(mExpectedValueInterval.ValueOr(kDefaultExpectedValueInterval));
106+
__auto_type * timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue()
107+
? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()]
108+
: nil;
109+
110+
[device writeAttributeWithEndpointID:endpoint
111+
clusterID:cluster
112+
attributeID:attribute
113+
value:value
114+
expectedValueInterval:expectedValueInterval
115+
timedWriteTimeout:timedWriteTimeout];
116+
117+
SetCommandExitStatus(CHIP_NO_ERROR);
118+
return CHIP_NO_ERROR;
119+
}
120+
90121
protected:
91122
WriteAttribute(const char * _Nonnull attributeName)
92123
: ModelCommand("write")
@@ -95,6 +126,14 @@ class WriteAttribute : public ModelCommand {
95126
// Subclasses are responsible for calling AddArguments.
96127
}
97128

129+
void AddCommonByIdArguments()
130+
{
131+
AddArgument("use-mtr-device", 0, 1, &mUseMTRDevice,
132+
"Use MTRDevice instead of MTRBaseDevice to send this command. Default is false.");
133+
AddArgument("expectedValueInterval", 0, UINT32_MAX, &mExpectedValueInterval, "When the write is issued using an MTRDevice (via –use-mtr-device), specify the maximum interval (in milliseconds) during which reads of the attribute will return the expected value. The default is 60000 milliseconds (60 seconds).");
134+
AddArguments();
135+
}
136+
98137
void AddArguments()
99138
{
100139
AddArgument("timedInteractionTimeoutMs", 0, UINT16_MAX, &mTimedInteractionTimeoutMs,
@@ -104,6 +143,7 @@ class WriteAttribute : public ModelCommand {
104143
}
105144

106145
chip::Optional<uint16_t> mTimedInteractionTimeoutMs;
146+
chip::Optional<uint32_t> mExpectedValueInterval;
107147
chip::Optional<uint32_t> mDataVersion;
108148

109149
private:

examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h

+4
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ class CHIPCommandBridge : public Command {
9797
// Will utilize an existing PASE connection if the device is being commissioned.
9898
MTRBaseDevice * BaseDeviceWithNodeId(chip::NodeId nodeId);
9999

100+
// Returns the MTRDevice for the specified node ID.
101+
// Will utilize an existing PASE connection if the device is being commissioned.
102+
MTRDevice * DeviceWithNodeId(chip::NodeId nodeId);
103+
100104
// Will log the given string and given error (as progress if success, error
101105
// if failure).
102106
void LogNSError(const char * logString, NSError * error);

examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm

+11
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,17 @@
285285
?: [MTRBaseDevice deviceWithNodeID:@(nodeId) controller:controller];
286286
}
287287

288+
MTRDevice * CHIPCommandBridge::DeviceWithNodeId(chip::NodeId nodeId)
289+
{
290+
__auto_type * controller = CurrentCommissioner();
291+
VerifyOrReturnValue(nil != controller, nil);
292+
293+
__auto_type * device = [MTRDevice deviceWithNodeID:@(nodeId) controller:controller];
294+
VerifyOrReturnValue(nil != device, nil);
295+
296+
return device;
297+
}
298+
288299
void CHIPCommandBridge::StopCommissioners()
289300
{
290301
for (auto & pair : mControllers) {

0 commit comments

Comments
 (0)