diff --git a/examples/chip-tool/commands/clusters/ReportCommand.h b/examples/chip-tool/commands/clusters/ReportCommand.h index 694507c410c7f8..8819ff08c67e55 100644 --- a/examples/chip-tool/commands/clusters/ReportCommand.h +++ b/examples/chip-tool/commands/clusters/ReportCommand.h @@ -418,7 +418,20 @@ class ReadAll : public ReadCommand public: ReadAll(CredentialIssuerCommands * credsIssuerConfig) : ReadCommand("read-all", credsIssuerConfig) { - AddArgument("fabric-filtered", 0, 1, &mFabricFiltered); + AddArgument("cluster-ids", 0, UINT32_MAX, &mClusterIds, + "Comma-separated list of cluster ids to read from (e.g. \"6\" or \"8,0x201\").\n Allowed to be 0xFFFFFFFF to " + "indicate a wildcard cluster."); + AddArgument("attribute-ids", 0, UINT32_MAX, &mAttributeIds, + "Comma-separated list of attribute ids to read (e.g. \"0\" or \"1,0xFFFC,0xFFFD\").\n Allowed to be " + "0xFFFFFFFF to indicate a wildcard attribute."); + AddArgument("event-ids", 0, UINT32_MAX, &mEventIds, + "Comma-separated list of event ids to read (e.g. \"0\" or \"1,2,3\").\n Allowed to be " + "0xFFFFFFFF to indicate a wildcard event."); + 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(); } @@ -432,9 +445,62 @@ class ReadAll : public ReadCommand CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override { - return ReadCommand::ReadAll(device, endpointIds, mFabricFiltered); + return ReadCommand::ReadAll(device, endpointIds, mClusterIds, mAttributeIds, mEventIds, mFabricFiltered, mDataVersions, + mEventNumber); + } + +private: + std::vector mClusterIds; + std::vector mAttributeIds; + std::vector mEventIds; + + chip::Optional mFabricFiltered; + chip::Optional> mDataVersions; + chip::Optional mEventNumber; +}; + +class SubscribeAll : public SubscribeCommand +{ +public: + SubscribeAll(CredentialIssuerCommands * credsIssuerConfig) : SubscribeCommand("subscribe-all", credsIssuerConfig) + { + AddArgument("cluster-ids", 0, UINT32_MAX, &mClusterIds, + "Comma-separated list of cluster ids to read from (e.g. \"6\" or \"8,0x201\").\n Allowed to be 0xFFFFFFFF to " + "indicate a wildcard cluster."); + AddArgument("attribute-ids", 0, UINT32_MAX, &mAttributeIds, + "Comma-separated list of attribute ids to read (e.g. \"0\" or \"1,0xFFFC,0xFFFD\").\n Allowed to be " + "0xFFFFFFFF to indicate a wildcard attribute."); + AddArgument("event-ids", 0, UINT32_MAX, &mEventIds, + "Comma-separated list of event ids to read (e.g. \"0\" or \"1,2,3\").\n Allowed to be " + "0xFFFFFFFF to indicate a wildcard event."); + 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(); + } + + ~SubscribeAll() {} + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + return SubscribeCommand::SubscribeAll(device, endpointIds, mClusterIds, mAttributeIds, mEventIds, mMinInterval, + mMaxInterval, mFabricFiltered, mEventNumber, mKeepSubscriptions); } private: + std::vector mClusterIds; + std::vector mAttributeIds; + std::vector mEventIds; + + uint16_t mMinInterval; + uint16_t mMaxInterval; chip::Optional mFabricFiltered; + chip::Optional mEventNumber; + chip::Optional mKeepSubscriptions; }; diff --git a/examples/chip-tool/templates/commands.zapt b/examples/chip-tool/templates/commands.zapt index 2600ce10eeaa1f..eff75beb058cce 100644 --- a/examples/chip-tool/templates/commands.zapt +++ b/examples/chip-tool/templates/commands.zapt @@ -138,6 +138,7 @@ void registerClusterAny(Commands & commands, CredentialIssuerCommands * credsIss make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // }; commands.Register(clusterName, clusterCommands); diff --git a/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp b/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp index 9a3c738b45d373..ab15e920fb8cbb 100644 --- a/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp +++ b/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp @@ -449,35 +449,129 @@ void InteractionModelReports::CleanupReadClient(ReadClient * aReadClient) mReadClients.end()); } -CHIP_ERROR InteractionModelReports::ReadAll(DeviceProxy * device, std::vector endpointIds, - const Optional & fabricFiltered) +CHIP_ERROR InteractionModelReports::ReportAll(chip::DeviceProxy * device, std::vector endpointIds, + std::vector clusterIds, std::vector attributeIds, + std::vector eventIds, + chip::app::ReadClient::InteractionType interactionType, uint16_t minInterval, + uint16_t maxInterval, const chip::Optional & fabricFiltered, + const chip::Optional> & dataVersions, + const chip::Optional & eventNumber, + const chip::Optional & keepSubscriptions) { + const size_t endpointCount = endpointIds.size(); + const size_t clusterCount = clusterIds.size(); + const size_t attributeCount = attributeIds.size(); + const size_t eventCount = eventIds.size(); + + // TODO Add data version supports + // TODO Add isUrgents supports + + VerifyOrReturnError(endpointCount > 0 && endpointCount <= kMaxAllowedPaths, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(clusterCount > 0 && clusterCount <= kMaxAllowedPaths, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(attributeCount > 0 && attributeCount <= kMaxAllowedPaths, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(eventCount > 0 && eventCount <= kMaxAllowedPaths, CHIP_ERROR_INVALID_ARGUMENT); + + const bool hasSameIdsCount = (clusterCount == (attributeCount + eventCount)) && (clusterCount == endpointCount); + if (!hasSameIdsCount) + { + ChipLogError(chipTool, + "\nCommand targetting a combination of attribute and event paths needs to have has many clusters and " + "endpoints than the number of attribute and events combined.\n" + "For example if there are 2 attributes and 1 event, the command expects 3 clusters and 3 endpoints.\n" + "Clusters and endpoints ids will be consumed first to populate the attribute paths of the request, and then " + "to populate the event paths of the request.\n\n" + "For example the following arguments:\n" + "\tcluster-ids: 6,6,0X28\n" + "\tendpoint-ids: 1,1,0\n" + "\tattribute-ids: 0,0x4001\n" + "\tevent-ids: 0\n" + "\n" + "will create the following paths:\n" + "\t{cluster: 6, endpoint: 1, attribute: 0}\n" + "\t{cluster: 6, endpoint: 1, attribute: 0x4001}\n" + "\t{cluster: 0x28, endpoint: 0, event: 0}\n"); + return CHIP_ERROR_INVALID_ARGUMENT; + } + AttributePathParams attributePathParams[kMaxAllowedPaths]; EventPathParams eventPathParams[kMaxAllowedPaths]; - auto pathsCount = endpointIds.size(); - VerifyOrReturnError(pathsCount > 0 && pathsCount <= kMaxAllowedPaths, CHIP_ERROR_INVALID_ARGUMENT); - + size_t attributeIndex = 0; + size_t eventIndex = 0; + size_t pathsCount = clusterCount; for (size_t i = 0; i < pathsCount; i++) { - auto endpointId = endpointIds.at(i); - attributePathParams[i].mEndpointId = endpointId; - eventPathParams[i].mEndpointId = endpointId; + auto clusterId = clusterIds.at(i); + auto endpointId = endpointIds.at(i); + + if (attributeIndex < attributeIds.size()) + { + auto attributeId = attributeIds.at(attributeIndex); + + if (endpointId != kInvalidEndpointId) + { + attributePathParams[attributeIndex].mEndpointId = endpointId; + } + + if (clusterId != kInvalidClusterId) + { + attributePathParams[attributeIndex].mClusterId = clusterId; + } + + if (attributeId != kInvalidAttributeId) + { + attributePathParams[attributeIndex].mAttributeId = attributeId; + } + + attributeIndex++; + } + else if (eventIndex < eventIds.size()) + { + auto eventId = eventIds.at(eventIndex); + + if (endpointId != kInvalidEndpointId) + { + eventPathParams[eventIndex].mEndpointId = endpointId; + } + + if (clusterId != kInvalidClusterId) + { + eventPathParams[eventIndex].mClusterId = clusterId; + } + + if (eventId != kInvalidEventId) + { + eventPathParams[eventIndex].mEventId = eventId; + } + + eventIndex++; + } } ReadPrepareParams params(device->GetSecureSession().Value()); params.mpEventPathParamsList = eventPathParams; - params.mEventPathParamsListSize = pathsCount; + params.mEventPathParamsListSize = eventCount; + params.mEventNumber = eventNumber; params.mpAttributePathParamsList = attributePathParams; - params.mAttributePathParamsListSize = pathsCount; + params.mAttributePathParamsListSize = attributeCount; if (fabricFiltered.HasValue()) { params.mIsFabricFiltered = fabricFiltered.Value(); } + if (interactionType == ReadClient::InteractionType::Subscribe) + { + params.mMinIntervalFloorSeconds = minInterval; + params.mMaxIntervalCeilingSeconds = maxInterval; + if (keepSubscriptions.HasValue()) + { + params.mKeepSubscriptions = keepSubscriptions.Value(); + } + } + auto client = std::make_unique(InteractionModelEngine::GetInstance(), device->GetExchangeManager(), - mBufferedReadAdapter, ReadClient::InteractionType::Read); + mBufferedReadAdapter, interactionType); ReturnErrorOnFailure(client->SendRequest(params)); mReadClients.push_back(std::move(client)); return CHIP_NO_ERROR; diff --git a/src/app/tests/suites/commands/interaction_model/InteractionModel.h b/src/app/tests/suites/commands/interaction_model/InteractionModel.h index 157195bf2a8352..6d444ef6e1c9db 100644 --- a/src/app/tests/suites/commands/interaction_model/InteractionModel.h +++ b/src/app/tests/suites/commands/interaction_model/InteractionModel.h @@ -108,7 +108,35 @@ class InteractionModelReports const chip::Optional> & isUrgents = chip::NullOptional); CHIP_ERROR ReadAll(chip::DeviceProxy * device, std::vector endpointIds, - const chip::Optional & fabricFiltered = chip::Optional(true)); + std::vector clusterIds, std::vector attributeIds, + std::vector eventIds, + const chip::Optional & fabricFiltered = chip::Optional(true), + const chip::Optional> & dataVersions = chip::NullOptional, + const chip::Optional & eventNumber = chip::NullOptional) + { + return ReportAll(device, endpointIds, clusterIds, attributeIds, eventIds, chip::app::ReadClient::InteractionType::Read, 0, + 0, fabricFiltered, dataVersions, eventNumber); + } + + CHIP_ERROR SubscribeAll(chip::DeviceProxy * device, std::vector endpointIds, + std::vector clusterIds, std::vector attributeIds, + std::vector eventIds, uint16_t minInterval = 0, uint16_t maxInterval = 0, + const chip::Optional & fabricFiltered = chip::Optional(true), + const chip::Optional & eventNumber = chip::NullOptional, + const chip::Optional & keepSubscriptions = chip::NullOptional) + { + return ReportAll(device, endpointIds, clusterIds, attributeIds, eventIds, chip::app::ReadClient::InteractionType::Subscribe, + minInterval, maxInterval, fabricFiltered, chip::NullOptional, eventNumber, keepSubscriptions); + } + + CHIP_ERROR ReportAll(chip::DeviceProxy * device, std::vector endpointIds, + std::vector clusterIds, std::vector attributeIds, + std::vector eventIds, chip::app::ReadClient::InteractionType interactionType, + uint16_t minInterval = 0, uint16_t maxInterval = 0, + const chip::Optional & fabricFiltered = chip::Optional(true), + const chip::Optional> & dataVersions = chip::NullOptional, + const chip::Optional & eventNumber = chip::NullOptional, + const chip::Optional & keepSubscriptions = chip::NullOptional); void Shutdown() { mReadClients.clear(); } diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 6bee2ed94362b9..2bbbd0fdd8a949 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -13133,6 +13133,7 @@ void registerClusterAny(Commands & commands, CredentialIssuerCommands * credsIss make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // }; commands.Register(clusterName, clusterCommands);