From 2a15ff5a1afcc4d54fa82f00c31d7f3f6449a4da Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Fri, 28 Jul 2023 18:19:58 +0200 Subject: [PATCH] [chip-tool] Add read-none/subscribe-none commands (#28327) * [chip-tool] Add read-none/subscribe-none commands * Update __init__.py --- .../commands/clusters/ModelCommand.h | 23 ++++---- .../commands/clusters/ReportCommand.h | 52 +++++++++++++++++++ .../matter_chip_tool_adapter/encoder.py | 16 ++++++ examples/chip-tool/templates/commands.zapt | 2 + scripts/tests/chiptest/__init__.py | 1 + .../suites/TestReadNoneSubscribeNone.yaml | 40 ++++++++++++++ .../interaction_model/InteractionModel.cpp | 34 ++++++++++++ .../interaction_model/InteractionModel.h | 9 ++++ .../zap-generated/cluster/Commands.h | 2 + 9 files changed, 169 insertions(+), 10 deletions(-) create mode 100644 src/app/tests/suites/TestReadNoneSubscribeNone.yaml diff --git a/examples/chip-tool/commands/clusters/ModelCommand.h b/examples/chip-tool/commands/clusters/ModelCommand.h index 5c612365b2ee24..0b6339ab60f5ed 100644 --- a/examples/chip-tool/commands/clusters/ModelCommand.h +++ b/examples/chip-tool/commands/clusters/ModelCommand.h @@ -33,21 +33,24 @@ class ModelCommand : public CHIPCommand mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this), mSupportsMultipleEndpoints(supportsMultipleEndpoints) {} - void AddArguments() + void AddArguments(bool skipEndpoints = false) { AddArgument( "destination-id", 0, UINT64_MAX, &mDestinationId, "64-bit node or group identifier.\n Group identifiers are detected by being in the 0xFFFF'FFFF'FFFF'xxxx range."); - if (mSupportsMultipleEndpoints) + if (skipEndpoints == false) { - AddArgument("endpoint-ids", 0, UINT16_MAX, &mEndPointId, - "Comma-separated list of endpoint ids (e.g. \"1\" or \"1,2,3\").\n Allowed to be 0xFFFF to indicate a " - "wildcard endpoint."); - } - else - { - AddArgument("endpoint-id-ignored-for-group-commands", 0, UINT16_MAX, &mEndPointId, - "Endpoint the command is targeted at."); + if (mSupportsMultipleEndpoints) + { + AddArgument("endpoint-ids", 0, UINT16_MAX, &mEndPointId, + "Comma-separated list of endpoint ids (e.g. \"1\" or \"1,2,3\").\n Allowed to be 0xFFFF to indicate a " + "wildcard endpoint."); + } + else + { + AddArgument("endpoint-id-ignored-for-group-commands", 0, UINT16_MAX, &mEndPointId, + "Endpoint the command is targeted at."); + } } AddArgument("timeout", 0, UINT16_MAX, &mTimeout); } diff --git a/examples/chip-tool/commands/clusters/ReportCommand.h b/examples/chip-tool/commands/clusters/ReportCommand.h index e90fb5ddf28f14..eefd938c2d0717 100644 --- a/examples/chip-tool/commands/clusters/ReportCommand.h +++ b/examples/chip-tool/commands/clusters/ReportCommand.h @@ -415,6 +415,33 @@ class SubscribeEvent : public SubscribeCommand std::vector mEventIds; }; +class ReadNone : public ReadCommand +{ +public: + ReadNone(CredentialIssuerCommands * credsIssuerConfig) : ReadCommand("read-none", credsIssuerConfig) + { + AddArgument("fabric-filtered", 0, 1, &mFabricFiltered, + "Boolean indicating whether to do a fabric-filtered read. Defaults to true."); + AddArgument("data-versions", 0, UINT32_MAX, &mDataVersions, + "Comma-separated list of data versions for the clusters being read."); + AddArgument("event-min", 0, UINT64_MAX, &mEventNumber); + ReadCommand::AddArguments(true /* skipEndpoints */); + } + + ~ReadNone() {} + + void OnDone(chip::app::ReadClient * aReadClient) override + { + InteractionModelReports::CleanupReadClient(aReadClient); + SetCommandExitStatus(mError); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + return ReadCommand::ReadNone(device); + } +}; + class ReadAll : public ReadCommand { public: @@ -456,6 +483,31 @@ class ReadAll : public ReadCommand std::vector mEventIds; }; +class SubscribeNone : public SubscribeCommand +{ +public: + SubscribeNone(CredentialIssuerCommands * credsIssuerConfig) : SubscribeCommand("subscribe-none", credsIssuerConfig) + { + AddArgument("min-interval", 0, UINT16_MAX, &mMinInterval, + "The requested minimum interval between reports. Sets MinIntervalFloor in the Subscribe Request."); + AddArgument("max-interval", 0, UINT16_MAX, &mMaxInterval, + "The requested maximum interval between reports. Sets MaxIntervalCeiling in the Subscribe Request."); + AddArgument("fabric-filtered", 0, 1, &mFabricFiltered, + "Boolean indicating whether to do a fabric-filtered read. Defaults to true."); + AddArgument("event-min", 0, UINT64_MAX, &mEventNumber); + AddArgument("keepSubscriptions", 0, 1, &mKeepSubscriptions, + "false - Terminate existing subscriptions from initiator.\n true - Leave existing subscriptions in place."); + SubscribeCommand::AddArguments(true /* skipEndpoints */); + } + + ~SubscribeNone() {} + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + return SubscribeCommand::SubscribeNone(device); + } +}; + class SubscribeAll : public SubscribeCommand { public: diff --git a/examples/chip-tool/py_matter_chip_tool_adapter/matter_chip_tool_adapter/encoder.py b/examples/chip-tool/py_matter_chip_tool_adapter/matter_chip_tool_adapter/encoder.py index 2c02811f865845..e57bfe29b6af76 100644 --- a/examples/chip-tool/py_matter_chip_tool_adapter/matter_chip_tool_adapter/encoder.py +++ b/examples/chip-tool/py_matter_chip_tool_adapter/matter_chip_tool_adapter/encoder.py @@ -22,7 +22,9 @@ 'SubscribeById', 'ReadEventById', 'SubscribeEventById', + 'ReadNone', 'ReadAll', + 'SubscribeNone', 'SubscribeAll', ] @@ -79,6 +81,9 @@ 'EventId': 'event-id', }, }, + 'ReadNone': { + 'alias': 'read-none', + }, 'ReadAll': { 'alias': 'read-all', 'arguments': { @@ -87,6 +92,9 @@ 'EventId': 'event-ids', }, }, + 'SubscribeNone': { + 'alias': 'subscribe-none', + }, 'SubscribeAll': { 'alias': 'subscribe-all', 'arguments': { @@ -99,6 +107,14 @@ }, 'AnyCommands': { 'alias': 'any', + 'commands': { + 'ReadNone': { + 'has_endpoint': False, + }, + 'SubscribeNone': { + 'has_endpoint': False, + } + } }, 'CommissionerCommands': { 'alias': 'pairing', diff --git a/examples/chip-tool/templates/commands.zapt b/examples/chip-tool/templates/commands.zapt index 60d327821b05d5..224ea8e5f8c2eb 100644 --- a/examples/chip-tool/templates/commands.zapt +++ b/examples/chip-tool/templates/commands.zapt @@ -132,7 +132,9 @@ void registerClusterAny(Commands & commands, CredentialIssuerCommands * credsIss make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // }; diff --git a/scripts/tests/chiptest/__init__.py b/scripts/tests/chiptest/__init__.py index 2b761d95684baf..4e5390495bdac5 100644 --- a/scripts/tests/chiptest/__init__.py +++ b/scripts/tests/chiptest/__init__.py @@ -138,6 +138,7 @@ def _GetInDevelopmentTests() -> Set[str]: "TestAttributesById.yaml", # chip-repl does not support AnyCommands (06/06/2023) "TestCommandsById.yaml", # chip-repl does not support AnyCommands (06/06/2023) "TestEventsById.yaml", # chip-repl does not support AnyCommands (06/06/2023) + "TestReadNoneSubscribeNone.yaml", # chip-repl does not support AnyCommands (07/27/2023) "Test_TC_DRLK_2_8.yaml", # Test fails only in chip-repl: Refer--> https://github.com/project-chip/connectedhomeip/pull/27011#issuecomment-1593339855 "Test_TC_ACE_1_6.yaml", # Test fails only in chip-repl: Refer--> https://github.com/project-chip/connectedhomeip/pull/27910#issuecomment-1632485584 "Test_TC_PSCFG_1_1.yaml", # Power source configuration cluster is deprecated and removed from all-clusters diff --git a/src/app/tests/suites/TestReadNoneSubscribeNone.yaml b/src/app/tests/suites/TestReadNoneSubscribeNone.yaml new file mode 100644 index 00000000000000..928dde69aecb8d --- /dev/null +++ b/src/app/tests/suites/TestReadNoneSubscribeNone.yaml @@ -0,0 +1,40 @@ +# Copyright (c) 2023 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. + +name: ReadNone/SuscribeNone Tests + +config: + nodeId: 0x12344321 + cluster: "Unit Testing" + +tests: + - label: "Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "Read Request Message with no paths." + cluster: "AnyCommands" + command: "ReadNone" + + - label: "Subscribe Request Message with no paths." + cluster: "AnyCommands" + command: "SubscribeNone" + minInterval: 1 + maxInterval: 2 + response: + error: INVALID_ACTION diff --git a/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp b/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp index c6c68441a127d4..a2c418435990e4 100644 --- a/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp +++ b/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp @@ -503,6 +503,40 @@ void InteractionModelReports::CleanupReadClient(ReadClient * aReadClient) mReadClients.end()); } +CHIP_ERROR InteractionModelReports::ReportNone(chip::DeviceProxy * device, chip::app::ReadClient::InteractionType interactionType) +{ + AttributePathParams attributePathParams[kMaxAllowedPaths]; + EventPathParams eventPathParams[kMaxAllowedPaths]; + + ReadPrepareParams params(device->GetSecureSession().Value()); + params.mpEventPathParamsList = eventPathParams; + params.mEventPathParamsListSize = 0; + params.mEventNumber = mEventNumber; + params.mpAttributePathParamsList = attributePathParams; + params.mAttributePathParamsListSize = 0; + + if (mFabricFiltered.HasValue()) + { + params.mIsFabricFiltered = mFabricFiltered.Value(); + } + + if (interactionType == ReadClient::InteractionType::Subscribe) + { + params.mMinIntervalFloorSeconds = mMinInterval; + params.mMaxIntervalCeilingSeconds = mMaxInterval; + if (mKeepSubscriptions.HasValue()) + { + params.mKeepSubscriptions = mKeepSubscriptions.Value(); + } + } + + auto client = std::make_unique(InteractionModelEngine::GetInstance(), device->GetExchangeManager(), + mBufferedReadAdapter, interactionType); + ReturnErrorOnFailure(client->SendRequest(params)); + mReadClients.push_back(std::move(client)); + return CHIP_NO_ERROR; +} + CHIP_ERROR InteractionModelReports::ReportAll(chip::DeviceProxy * device, std::vector endpointIds, std::vector clusterIds, std::vector attributeIds, std::vector eventIds, diff --git a/src/app/tests/suites/commands/interaction_model/InteractionModel.h b/src/app/tests/suites/commands/interaction_model/InteractionModel.h index f033349fb26249..c52ff744fac791 100644 --- a/src/app/tests/suites/commands/interaction_model/InteractionModel.h +++ b/src/app/tests/suites/commands/interaction_model/InteractionModel.h @@ -90,6 +90,8 @@ class InteractionModelReports std::vector clusterIds, std::vector eventIds, chip::app::ReadClient::InteractionType interactionType); + CHIP_ERROR ReadNone(chip::DeviceProxy * device) { return ReportNone(device, chip::app::ReadClient::InteractionType::Read); } + CHIP_ERROR ReadAll(chip::DeviceProxy * device, std::vector endpointIds, std::vector clusterIds, std::vector attributeIds, std::vector eventIds) @@ -97,6 +99,11 @@ class InteractionModelReports return ReportAll(device, endpointIds, clusterIds, attributeIds, eventIds, chip::app::ReadClient::InteractionType::Read); } + CHIP_ERROR SubscribeNone(chip::DeviceProxy * device) + { + return ReportNone(device, chip::app::ReadClient::InteractionType::Subscribe); + } + CHIP_ERROR SubscribeAll(chip::DeviceProxy * device, std::vector endpointIds, std::vector clusterIds, std::vector attributeIds, std::vector eventIds) @@ -105,6 +112,8 @@ class InteractionModelReports chip::app::ReadClient::InteractionType::Subscribe); } + CHIP_ERROR ReportNone(chip::DeviceProxy * device, chip::app::ReadClient::InteractionType interactionType); + CHIP_ERROR ReportAll(chip::DeviceProxy * device, std::vector endpointIds, std::vector clusterIds, std::vector attributeIds, std::vector eventIds, chip::app::ReadClient::InteractionType interactionType); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index e92d7f7c750d82..cc148609f900ff 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -19841,7 +19841,9 @@ void registerClusterAny(Commands & commands, CredentialIssuerCommands * credsIss make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // };