diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index ffa190a61bb62a..f2829660b0f725 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -15357,6 +15357,14 @@ "source": "client", "incoming": 1, "outgoing": 0 + }, + { + "name": "TestSimpleOptionalArgumentRequest", + "code": 19, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 } ], "attributes": [ diff --git a/src/app/clusters/test-cluster-server/test-cluster-server.cpp b/src/app/clusters/test-cluster-server/test-cluster-server.cpp index be4fbc61bc3316..f2c48dacbcda05 100644 --- a/src/app/clusters/test-cluster-server/test-cluster-server.cpp +++ b/src/app/clusters/test-cluster-server/test-cluster-server.cpp @@ -555,6 +555,16 @@ bool emberAfTestClusterClusterTimedInvokeRequestCallback(CommandHandler * comman return true; } +bool emberAfTestClusterClusterTestSimpleOptionalArgumentRequestCallback( + CommandHandler * commandObj, const ConcreteCommandPath & commandPath, + const Commands::TestSimpleOptionalArgumentRequest::DecodableType & commandData) +{ + Protocols::InteractionModel::Status status = commandData.arg1.HasValue() ? Protocols::InteractionModel::Status::Success + : Protocols::InteractionModel::Status::InvalidValue; + commandObj->AddStatus(commandPath, status); + return true; +} + // ----------------------------------------------------------------------------- // Plugin initialization diff --git a/src/app/tests/suites/TestCluster.yaml b/src/app/tests/suites/TestCluster.yaml index 4637cc60354832..bdd9fe265f8e63 100644 --- a/src/app/tests/suites/TestCluster.yaml +++ b/src/app/tests/suites/TestCluster.yaml @@ -2360,3 +2360,18 @@ tests: response: # SDK returning wrong error code here so far. errorWrongValue: UNSUPPORTED_CLUSTER + + # Tests for command with optional arguments + - label: + "Send a command that takes an optional parameter but do not set it." + command: "TestSimpleOptionalArgumentRequest" + response: + error: INVALID_VALUE + + - label: + "Send a command that takes an optional parameter but do not set it." + command: "TestSimpleOptionalArgumentRequest" + arguments: + values: + - name: "arg1" + value: 1 diff --git a/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml index 85830e5936851d..4fe7367e651eee 100644 --- a/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml @@ -362,6 +362,13 @@ limitations under the License. + + + Command that takes an optional argument which is bool. It responds with a success value if the optional is set to any value. + + + + Simple response for TestWithResponse with a simple return value diff --git a/src/controller/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index b975b554fdf496..61950cb67fa6a4 100644 --- a/src/controller/data_model/controller-clusters.zap +++ b/src/controller/data_model/controller-clusters.zap @@ -11623,6 +11623,14 @@ "source": "client", "incoming": 0, "outgoing": 1 + }, + { + "name": "TestSimpleOptionalArgumentRequest", + "code": 19, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 1 } ], "attributes": [ @@ -13264,4 +13272,4 @@ } ], "log": [] -} +} \ No newline at end of file diff --git a/src/controller/java/zap-generated/CHIPClusters-JNI.cpp b/src/controller/java/zap-generated/CHIPClusters-JNI.cpp index cc1aeb019c1f8d..7b28d830baa41d 100644 --- a/src/controller/java/zap-generated/CHIPClusters-JNI.cpp +++ b/src/controller/java/zap-generated/CHIPClusters-JNI.cpp @@ -24734,6 +24734,46 @@ JNI_METHOD(void, TestClusterCluster, testNullableOptionalRequest) onSuccess.release(); onFailure.release(); } +JNI_METHOD(void, TestClusterCluster, testSimpleOptionalArgumentRequest) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jobject arg1) +{ + chip::DeviceLayer::StackLock lock; + CHIP_ERROR err = CHIP_NO_ERROR; + TestClusterCluster * cppCluster; + + chip::app::Clusters::TestCluster::Commands::TestSimpleOptionalArgumentRequest::Type request; + + chip::JniReferences::GetInstance().GetOptionalValue(arg1, arg1); + request.arg1 = + chip::Optional(static_cast(chip::JniReferences::GetInstance().BooleanToPrimitive(arg1))); + + std::unique_ptr onSuccess( + Platform::New(callback), Platform::Delete); + std::unique_ptr onFailure( + Platform::New(callback), Platform::Delete); + VerifyOrReturn(onSuccess.get() != nullptr, + AndroidClusterExceptions::GetInstance().ReturnIllegalStateException( + env, callback, "Error creating native callback", CHIP_ERROR_NO_MEMORY)); + VerifyOrReturn(onFailure.get() != nullptr, + AndroidClusterExceptions::GetInstance().ReturnIllegalStateException( + env, callback, "Error creating native callback", CHIP_ERROR_NO_MEMORY)); + + cppCluster = reinterpret_cast(clusterPtr); + VerifyOrReturn(cppCluster != nullptr, + AndroidClusterExceptions::GetInstance().ReturnIllegalStateException( + env, callback, "Error getting native cluster", CHIP_ERROR_INCORRECT_STATE)); + + auto successFn = chip::Callback::Callback::FromCancelable(onSuccess->Cancel()); + auto failureFn = chip::Callback::Callback::FromCancelable(onFailure->Cancel()); + + err = cppCluster->InvokeCommand(request, onSuccess->mContext, successFn->mCall, failureFn->mCall); + VerifyOrReturn(err == CHIP_NO_ERROR, + AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error invoking command", + CHIP_ERROR_INCORRECT_STATE)); + + onSuccess.release(); + onFailure.release(); +} JNI_METHOD(void, TestClusterCluster, testSpecific)(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback) { chip::DeviceLayer::StackLock lock; diff --git a/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java b/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java index 7c2fd5d8021211..59b0d0a01eee69 100644 --- a/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java @@ -10832,6 +10832,11 @@ public void testNullableOptionalRequest( testNullableOptionalRequest(chipClusterPtr, callback, arg1); } + public void testSimpleOptionalArgumentRequest( + DefaultClusterCallback callback, Optional arg1) { + testSimpleOptionalArgumentRequest(chipClusterPtr, callback, arg1); + } + public void testSpecific(TestSpecificResponseCallback callback) { testSpecific(chipClusterPtr, callback); } @@ -10921,6 +10926,9 @@ private native void testNestedStructListArgumentRequest( private native void testNullableOptionalRequest( long chipClusterPtr, TestNullableOptionalResponseCallback Callback, Optional arg1); + private native void testSimpleOptionalArgumentRequest( + long chipClusterPtr, DefaultClusterCallback Callback, Optional arg1); + private native void testSpecific(long chipClusterPtr, TestSpecificResponseCallback Callback); private native void testStructArgumentRequest( diff --git a/src/controller/java/zap-generated/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/zap-generated/chip/devicecontroller/ClusterInfoMapping.java index 25ee693622aaca..24ef1229868ef7 100644 --- a/src/controller/java/zap-generated/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/zap-generated/chip/devicecontroller/ClusterInfoMapping.java @@ -8177,6 +8177,27 @@ public Map> getCommandMap() { testClustertestNullableOptionalRequestCommandParams); testClusterClusterInteractionInfoMap.put( "testNullableOptionalRequest", testClustertestNullableOptionalRequestInteractionInfo); + Map testClustertestSimpleOptionalArgumentRequestCommandParams = + new LinkedHashMap(); + CommandParameterInfo testClustertestSimpleOptionalArgumentRequestarg1CommandParameterInfo = + new CommandParameterInfo("arg1", boolean.class); + testClustertestSimpleOptionalArgumentRequestCommandParams.put( + "arg1", testClustertestSimpleOptionalArgumentRequestarg1CommandParameterInfo); + + // Populate commands + InteractionInfo testClustertestSimpleOptionalArgumentRequestInteractionInfo = + new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.TestClusterCluster) cluster) + .testSimpleOptionalArgumentRequest( + (DefaultClusterCallback) callback, + (Optional) commandArguments.get("arg1")); + }, + () -> new DelegatedDefaultClusterCallback(), + testClustertestSimpleOptionalArgumentRequestCommandParams); + testClusterClusterInteractionInfoMap.put( + "testSimpleOptionalArgumentRequest", + testClustertestSimpleOptionalArgumentRequestInteractionInfo); Map testClustertestSpecificCommandParams = new LinkedHashMap(); // Populate commands diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 3574e54de9d1b1..c5dba2d4c94151 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -3759,6 +3759,13 @@ class ChipClusters: "arg1": "int", }, }, + 0x00000013: { + "commandId": 0x00000013, + "commandName": "TestSimpleOptionalArgumentRequest", + "args": { + "arg1": "bool", + }, + }, 0x00000002: { "commandId": 0x00000002, "commandName": "TestSpecific", diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 099f941303bf94..1cc87e60e41424 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -25023,6 +25023,22 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ]) + @dataclass + class TestSimpleOptionalArgumentRequest(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x050F + command_id: typing.ClassVar[int] = 0x0013 + is_client: typing.ClassVar[bool] = True + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor( + Label="arg1", Tag=0, Type=typing.Optional[bool]), + ]) + + arg1: 'typing.Optional[bool]' = None + class Attributes: @dataclass class Boolean(ClusterAttributeDescriptor): diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h index 735640ef78714e..f0738562a57d52 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h @@ -3295,6 +3295,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)testNullableOptionalRequestWithParams:(CHIPTestClusterClusterTestNullableOptionalRequestParams * _Nullable)params completionHandler:(void (^)(CHIPTestClusterClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler; +- (void)testSimpleOptionalArgumentRequestWithParams: + (CHIPTestClusterClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params + completionHandler:(StatusCompletion)completionHandler; - (void)testSpecificWithCompletionHandler:(void (^)(CHIPTestClusterClusterTestSpecificResponseParams * _Nullable data, NSError * _Nullable error))completionHandler; - (void)testStructArgumentRequestWithParams:(CHIPTestClusterClusterTestStructArgumentRequestParams *)params diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm index e19fe0337c8027..823de89e72ad37 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm @@ -16899,6 +16899,31 @@ new CHIPTestClusterClusterTestNullableOptionalResponseCallbackBridge( }); } +- (void)testSimpleOptionalArgumentRequestWithParams: + (CHIPTestClusterClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params + completionHandler:(StatusCompletion)completionHandler +{ + ListFreer listFreer; + TestCluster::Commands::TestSimpleOptionalArgumentRequest::Type request; + if (params != nil) { + if (params.arg1 != nil) { + auto & definedValue_0 = request.arg1.Emplace(); + definedValue_0 = params.arg1.boolValue; + } + } + + new CHIPCommandSuccessCallbackBridge( + self.callbackQueue, + ^(NSError * _Nullable error, id _Nullable value) { + completionHandler(error); + }, + ^(Cancelable * success, Cancelable * failure) { + auto successFn = Callback::FromCancelable(success); + auto failureFn = Callback::FromCancelable(failure); + return self.cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall); + }); +} + - (void)testSpecificWithCompletionHandler:(void (^)(CHIPTestClusterClusterTestSpecificResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/CHIPCommandPayloadsObjc.h index bc38038467073c..7162d7dc269979 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPCommandPayloadsObjc.h @@ -1931,6 +1931,11 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init; @end +@interface CHIPTestClusterClusterTestSimpleOptionalArgumentRequestParams : NSObject +@property (strong, nonatomic) NSNumber * _Nullable arg1; +- (instancetype)init; +@end + @interface CHIPMessagingClusterDisplayMessageParams : NSObject @property (strong, nonatomic) NSNumber * _Nonnull messageId; @property (strong, nonatomic) NSNumber * _Nonnull messageControl; diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/CHIPCommandPayloadsObjc.mm index 86f04acf55e03c..7d34f5b44d8fe6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPCommandPayloadsObjc.mm @@ -4120,6 +4120,17 @@ - (instancetype)init } @end +@implementation CHIPTestClusterClusterTestSimpleOptionalArgumentRequestParams +- (instancetype)init +{ + if (self = [super init]) { + + _arg1 = nil; + } + return self; +} +@end + @implementation CHIPMessagingClusterDisplayMessageParams - (instancetype)init { diff --git a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m index b6ef2e4f78f2f4..b676d9e2d68b39 100644 --- a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m +++ b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m @@ -26755,6 +26755,52 @@ - (void)testSendClusterTestCluster_000294_ReadAttribute [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } +- (void)testSendClusterTestCluster_000295_TestSimpleOptionalArgumentRequest +{ + XCTestExpectation * expectation = + [self expectationWithDescription:@"Send a command that takes an optional parameter but do not set it."]; + + CHIPDevice * device = GetConnectedDevice(); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPTestTestCluster * cluster = [[CHIPTestTestCluster alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + __auto_type * params = [[CHIPTestClusterClusterTestSimpleOptionalArgumentRequestParams alloc] init]; + [cluster + testSimpleOptionalArgumentRequestWithParams:params + completionHandler:^(NSError * _Nullable err) { + NSLog(@"Send a command that takes an optional parameter but do not set it. Error: %@", err); + + XCTAssertEqual([CHIPErrorTestUtils errorToZCLErrorCode:err], EMBER_ZCL_STATUS_INVALID_VALUE); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} +- (void)testSendClusterTestCluster_000296_TestSimpleOptionalArgumentRequest +{ + XCTestExpectation * expectation = + [self expectationWithDescription:@"Send a command that takes an optional parameter but do not set it."]; + + CHIPDevice * device = GetConnectedDevice(); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPTestTestCluster * cluster = [[CHIPTestTestCluster alloc] initWithDevice:device endpoint:1 queue:queue]; + XCTAssertNotNil(cluster); + + __auto_type * params = [[CHIPTestClusterClusterTestSimpleOptionalArgumentRequestParams alloc] init]; + params.arg1 = [NSNumber numberWithBool:1]; + [cluster + testSimpleOptionalArgumentRequestWithParams:params + completionHandler:^(NSError * _Nullable err) { + NSLog(@"Send a command that takes an optional parameter but do not set it. Error: %@", err); + + XCTAssertEqual([CHIPErrorTestUtils errorToZCLErrorCode:err], 0); + + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} - (void)testSendClusterTestSaveAs_000000_WaitForCommissionee { diff --git a/zzz_generated/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp index 9912a355878ef4..ee163b34d597d1 100644 --- a/zzz_generated/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/all-clusters-app/zap-generated/IMClusterCommandHandler.cpp @@ -1739,6 +1739,16 @@ void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandP } break; } + case Commands::TestSimpleOptionalArgumentRequest::Id: { + Commands::TestSimpleOptionalArgumentRequest::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = + emberAfTestClusterClusterTestSimpleOptionalArgumentRequestCallback(apCommandObj, aCommandPath, commandData); + } + break; + } case Commands::TestSpecific::Id: { Commands::TestSpecific::DecodableType commandData; TLVError = DataModel::Decode(aDataTlv, commandData); diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index 18d784fbf686cc..35af34a06322fe 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -14726,6 +14726,12 @@ bool emberAfTestClusterClusterSimpleStructEchoRequestCallback( bool emberAfTestClusterClusterTimedInvokeRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::TestCluster::Commands::TimedInvokeRequest::DecodableType & commandData); +/** + * @brief Test Cluster Cluster TestSimpleOptionalArgumentRequest Command callback (from client) + */ +bool emberAfTestClusterClusterTestSimpleOptionalArgumentRequestCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::TestCluster::Commands::TestSimpleOptionalArgumentRequest::DecodableType & commandData); /** * @brief Messaging Cluster DisplayMessage Command callback (from server) */ diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index caa6c462b90537..36f8cf3f2ff8de 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -18104,6 +18104,40 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) return CHIP_NO_ERROR; } } // namespace TimedInvokeRequest. +namespace TestSimpleOptionalArgumentRequest { +CHIP_ERROR Type::Encode(TLV::TLVWriter & writer, TLV::Tag tag) const +{ + TLV::TLVType outer; + ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer)); + ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::kArg1)), arg1)); + ReturnErrorOnFailure(writer.EndContainer(outer)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + TLV::TLVType outer; + VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE); + ReturnErrorOnFailure(reader.EnterContainer(outer)); + while ((err = reader.Next()) == CHIP_NO_ERROR) + { + VerifyOrReturnError(TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG); + switch (TLV::TagNumFromTag(reader.GetTag())) + { + case to_underlying(Fields::kArg1): + ReturnErrorOnFailure(DataModel::Decode(reader, arg1)); + break; + default: + break; + } + } + + VerifyOrReturnError(err == CHIP_END_OF_TLV, err); + ReturnErrorOnFailure(reader.ExitContainer(outer)); + return CHIP_NO_ERROR; +} +} // namespace TestSimpleOptionalArgumentRequest. } // namespace Commands namespace Events { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 185efcd83e42fb..1e8c6b160e95bd 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -29283,6 +29283,11 @@ struct Type; struct DecodableType; } // namespace TimedInvokeRequest +namespace TestSimpleOptionalArgumentRequest { +struct Type; +struct DecodableType; +} // namespace TestSimpleOptionalArgumentRequest + } // namespace Commands namespace Commands { @@ -30356,6 +30361,38 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace TimedInvokeRequest +namespace TestSimpleOptionalArgumentRequest { +enum class Fields +{ + kArg1 = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::TestSimpleOptionalArgumentRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::TestCluster::Id; } + + Optional arg1; + + CHIP_ERROR Encode(TLV::TLVWriter & writer, TLV::Tag tag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::TestSimpleOptionalArgumentRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::TestCluster::Id; } + + Optional arg1; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace TestSimpleOptionalArgumentRequest } // namespace Commands namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/command-id.h b/zzz_generated/app-common/app-common/zap-generated/command-id.h index 24edaab289288e..e8a5414033816b 100644 --- a/zzz_generated/app-common/app-common/zap-generated/command-id.h +++ b/zzz_generated/app-common/app-common/zap-generated/command-id.h @@ -470,6 +470,7 @@ #define ZCL_TEST_COMPLEX_NULLABLE_OPTIONAL_REQUEST_COMMAND_ID (0x10) #define ZCL_SIMPLE_STRUCT_ECHO_REQUEST_COMMAND_ID (0x11) #define ZCL_TIMED_INVOKE_REQUEST_COMMAND_ID (0x12) +#define ZCL_TEST_SIMPLE_OPTIONAL_ARGUMENT_REQUEST_COMMAND_ID (0x13) // Commands for cluster: Messaging #define ZCL_DISPLAY_MESSAGE_COMMAND_ID (0x00) diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h index ff70d789328d00..bc4a5b4f07ccc6 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h @@ -1692,6 +1692,10 @@ namespace TimedInvokeRequest { static constexpr CommandId Id = 0x00000012; } // namespace TimedInvokeRequest +namespace TestSimpleOptionalArgumentRequest { +static constexpr CommandId Id = 0x00000013; +} // namespace TestSimpleOptionalArgumentRequest + } // namespace Commands } // namespace TestCluster diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 9a800a5409d3c2..7c621330dc0bed 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -36429,6 +36429,7 @@ class ReportTemperatureMeasurementClusterRevision : public ModelCommand | * TestNestedStructListArgumentRequest | 0x0B | | * TestNotHandled | 0x01 | | * TestNullableOptionalRequest | 0x0F | +| * TestSimpleOptionalArgumentRequest | 0x13 | | * TestSpecific | 0x02 | | * TestStructArgumentRequest | 0x07 | | * TestUnknownCommand | 0x03 | @@ -36795,6 +36796,29 @@ class TestClusterTestNullableOptionalRequest : public ModelCommand chip::app::Clusters::TestCluster::Commands::TestNullableOptionalRequest::Type mRequest; }; +/* + * Command TestSimpleOptionalArgumentRequest + */ +class TestClusterTestSimpleOptionalArgumentRequest : public ModelCommand +{ +public: + TestClusterTestSimpleOptionalArgumentRequest() : ModelCommand("test-simple-optional-argument-request") + { + AddArgument("Arg1", 0, 1, &mRequest.arg1); + ModelCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(ChipDevice * device, uint8_t endpointId) override + { + ChipLogProgress(chipTool, "Sending cluster (0x0000050F) command (0x00000013) on endpoint %" PRIu8, endpointId); + + return chip::Controller::InvokeCommand(device, this, OnDefaultSuccess, OnDefaultFailure, endpointId, mRequest); + } + +private: + chip::app::Clusters::TestCluster::Commands::TestSimpleOptionalArgumentRequest::Type mRequest; +}; + /* * Command TestSpecific */ @@ -57887,6 +57911,7 @@ void registerClusterTestCluster(Commands & commands) make_unique(), // make_unique(), // make_unique(), // + make_unique(), // make_unique(), // make_unique(), // make_unique(), // diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index d8e33aa0a151e9..9d3e0dbe6406db 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -33425,6 +33425,16 @@ class TestCluster : public TestCommand ChipLogProgress(chipTool, " ***** Test Step 294 : Read attribute from nonexistent cluster.\n"); err = TestReadAttributeFromNonexistentCluster_294(); break; + case 295: + ChipLogProgress(chipTool, + " ***** Test Step 295 : Send a command that takes an optional parameter but do not set it.\n"); + err = TestSendACommandThatTakesAnOptionalParameterButDoNotSetIt_295(); + break; + case 296: + ChipLogProgress(chipTool, + " ***** Test Step 296 : Send a command that takes an optional parameter but do not set it.\n"); + err = TestSendACommandThatTakesAnOptionalParameterButDoNotSetIt_296(); + break; } if (CHIP_NO_ERROR != err) @@ -33436,7 +33446,7 @@ class TestCluster : public TestCommand private: std::atomic_uint16_t mTestIndex; - const uint16_t mTestCount = 295; + const uint16_t mTestCount = 297; static void OnFailureCallback_6(void * context, EmberAfStatus status) { @@ -41937,6 +41947,57 @@ class TestCluster : public TestCommand } void OnSuccessResponse_294(const chip::app::DataModel::DecodableList & listInt8u) { ThrowSuccessResponse(); } + + CHIP_ERROR TestSendACommandThatTakesAnOptionalParameterButDoNotSetIt_295() + { + const chip::EndpointId endpoint = mEndpointId.HasValue() ? mEndpointId.Value() : 1; + using RequestType = chip::app::Clusters::TestCluster::Commands::TestSimpleOptionalArgumentRequest::Type; + + RequestType request; + + auto success = [](void * context, const typename RequestType::ResponseType & data) { + (static_cast(context))->OnSuccessResponse_295(); + }; + + auto failure = [](void * context, EmberAfStatus status) { + (static_cast(context))->OnFailureResponse_295(status); + }; + + ReturnErrorOnFailure(chip::Controller::InvokeCommand(mDevices[kIdentityAlpha], this, success, failure, endpoint, request)); + return CHIP_NO_ERROR; + } + + void OnFailureResponse_295(uint8_t status) + { + VerifyOrReturn(CheckValue("status", status, EMBER_ZCL_STATUS_INVALID_VALUE)); + NextTest(); + } + + void OnSuccessResponse_295() { ThrowSuccessResponse(); } + + CHIP_ERROR TestSendACommandThatTakesAnOptionalParameterButDoNotSetIt_296() + { + const chip::EndpointId endpoint = mEndpointId.HasValue() ? mEndpointId.Value() : 1; + using RequestType = chip::app::Clusters::TestCluster::Commands::TestSimpleOptionalArgumentRequest::Type; + + RequestType request; + request.arg1.Emplace() = 1; + + auto success = [](void * context, const typename RequestType::ResponseType & data) { + (static_cast(context))->OnSuccessResponse_296(); + }; + + auto failure = [](void * context, EmberAfStatus status) { + (static_cast(context))->OnFailureResponse_296(status); + }; + + ReturnErrorOnFailure(chip::Controller::InvokeCommand(mDevices[kIdentityAlpha], this, success, failure, endpoint, request)); + return CHIP_NO_ERROR; + } + + void OnFailureResponse_296(uint8_t status) { ThrowFailureResponse(); } + + void OnSuccessResponse_296() { NextTest(); } }; class TestClusterComplexTypes : public TestCommand diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp index 45b3233fe2f3a6..1814908a84c573 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp @@ -16237,6 +16237,48 @@ CHIP_ERROR TestClusterCluster::TestNullableOptionalRequest(Callback::Cancelable return err; } +CHIP_ERROR TestClusterCluster::TestSimpleOptionalArgumentRequest(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback, bool arg1) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + TLV::TLVWriter * writer = nullptr; + uint8_t argSeqNumber = 0; + + // Used when encoding non-empty command. Suppress error message when encoding empty commands. + (void) writer; + (void) argSeqNumber; + + VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE); + + app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, + TestCluster::Commands::TestSimpleOptionalArgumentRequest::Id, + (app::CommandPathFlags::kEndpointIdValid) }; + + CommandSenderHandle sender( + Platform::New(mDevice->GetInteractionModelDelegate(), mDevice->GetExchangeManager())); + + VerifyOrReturnError(sender != nullptr, CHIP_ERROR_NO_MEMORY); + + SuccessOrExit(err = sender->PrepareCommand(cmdParams)); + + VerifyOrExit((writer = sender->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + // arg1: boolean + SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), arg1)); + + SuccessOrExit(err = sender->FinishCommand()); + + // #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate. + mDevice->AddIMResponseHandler(sender.get(), onSuccessCallback, onFailureCallback); + + SuccessOrExit(err = mDevice->SendCommands(sender.get())); + + // We have successfully sent the command, and the callback handler will be responsible to free the object, release the object + // now. + sender.release(); +exit: + return err; +} + CHIP_ERROR TestClusterCluster::TestSpecific(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { CHIP_ERROR err = CHIP_NO_ERROR; diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h index a28444391ec309..cb3aa25de1ba97 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h @@ -2301,6 +2301,8 @@ class DLL_EXPORT TestClusterCluster : public ClusterBase CHIP_ERROR TestNotHandled(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); CHIP_ERROR TestNullableOptionalRequest(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, uint8_t arg1); + CHIP_ERROR TestSimpleOptionalArgumentRequest(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, + bool arg1); CHIP_ERROR TestSpecific(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); CHIP_ERROR TestStructArgumentRequest(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, uint8_t a, bool b, uint8_t c, chip::ByteSpan d, chip::CharSpan e, uint8_t f, float g,