From 1422600744101c63fde12af1b032ea9c7b0214f6 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Tue, 8 Mar 2022 19:12:08 +0100 Subject: [PATCH] [chip-tool] Allow passing multiple data versions for attributes reads (#15965) --- .../commands/clusters/ReportCommand.h | 48 ++++++++++++------- .../chip-tool/commands/common/Command.cpp | 30 +++++++++++- examples/chip-tool/commands/common/Command.h | 1 + 3 files changed, 60 insertions(+), 19 deletions(-) diff --git a/examples/chip-tool/commands/clusters/ReportCommand.h b/examples/chip-tool/commands/clusters/ReportCommand.h index dcc7acdbb1b6cd..160370f3634874 100644 --- a/examples/chip-tool/commands/clusters/ReportCommand.h +++ b/examples/chip-tool/commands/clusters/ReportCommand.h @@ -111,21 +111,28 @@ class ReportCommand : public ModelCommand, public chip::app::ReadClient::Callbac CHIP_ERROR ReportAttribute(ChipDevice * device, std::vector endpointIds, std::vector clusterIds, std::vector attributeIds, chip::app::ReadClient::InteractionType interactionType, uint16_t minInterval = 0, - uint16_t maxInterval = 0, - const chip::Optional & aDataVersion = chip::NullOptional) + uint16_t maxInterval = 0, + const chip::Optional> & dataVersions = chip::NullOptional) { - const size_t clusterCount = clusterIds.size(); - const size_t attributeCount = attributeIds.size(); - const size_t endpointCount = endpointIds.size(); + const size_t clusterCount = clusterIds.size(); + const size_t attributeCount = attributeIds.size(); + const size_t endpointCount = endpointIds.size(); + const size_t dataVersionsCount = dataVersions.HasValue() ? dataVersions.Value().size() : 0; VerifyOrReturnError(clusterCount > 0 && clusterCount <= kMaxAllowedPaths, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(attributeCount > 0 && attributeCount <= kMaxAllowedPaths, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(endpointCount > 0 && endpointCount <= kMaxAllowedPaths, CHIP_ERROR_INVALID_ARGUMENT); - - const bool hasSameIdsCount = (clusterCount == attributeCount) && (clusterCount == endpointCount); - const bool multipleClusters = clusterCount > 1 && attributeCount == 1 && endpointCount == 1; - const bool multipleAttributes = attributeCount > 1 && clusterCount == 1 && endpointCount == 1; - const bool multipleEndpoints = endpointCount > 1 && clusterCount == 1 && attributeCount == 1; + VerifyOrReturnError(dataVersionsCount <= kMaxAllowedPaths, CHIP_ERROR_INVALID_ARGUMENT); + + const bool hasSameIdsCount = (clusterCount == attributeCount) && (clusterCount == endpointCount) && + (dataVersionsCount == 0 || clusterCount == dataVersionsCount); + const bool multipleClusters = + clusterCount > 1 && attributeCount == 1 && endpointCount == 1 && (dataVersionsCount == 0 || dataVersionsCount == 1); + const bool multipleAttributes = + attributeCount > 1 && clusterCount == 1 && endpointCount == 1 && (dataVersionsCount == 0 || dataVersionsCount == 1); + const bool multipleEndpoints = + endpointCount > 1 && clusterCount == 1 && attributeCount == 1 && (dataVersionsCount == 0 || dataVersionsCount == 1); + const bool multipleDataVersions = dataVersionsCount > 1 && clusterCount == 1 && attributeCount == 1 && endpointCount == 1; size_t pathsCount = 0; if (hasSameIdsCount) @@ -144,6 +151,10 @@ class ReportCommand : public ModelCommand, public chip::app::ReadClient::Callbac { pathsCount = endpointCount; } + else if (multipleDataVersions) + { + pathsCount = dataVersionsCount; + } else { ChipLogError( @@ -157,11 +168,11 @@ class ReportCommand : public ModelCommand, public chip::app::ReadClient::Callbac return CHIP_ERROR_INVALID_ARGUMENT; } - chip::app::AttributePathParams attributePathParams[kMaxAllowedPaths]; - chip::app::DataVersionFilter dataVersionFilter[kMaxAllowedPaths]; - ChipLogProgress(chipTool, "Sending %sAttribute to:", interactionType == chip::app::ReadClient::InteractionType::Subscribe ? "Subscribe" : "Read"); + + chip::app::AttributePathParams attributePathParams[kMaxAllowedPaths]; + chip::app::DataVersionFilter dataVersionFilter[kMaxAllowedPaths]; for (size_t i = 0; i < pathsCount; i++) { chip::ClusterId clusterId = clusterIds.at((hasSameIdsCount || multipleClusters) ? i : 0); @@ -174,11 +185,12 @@ class ReportCommand : public ModelCommand, public chip::app::ReadClient::Callbac attributePathParams[i].mAttributeId = attributeId; attributePathParams[i].mEndpointId = endpointId; - if (aDataVersion.HasValue()) + if (dataVersions.HasValue()) { + chip::DataVersion dataVersion = dataVersions.Value().at((hasSameIdsCount || multipleDataVersions) ? i : 0); dataVersionFilter[i].mEndpointId = endpointId; dataVersionFilter[i].mClusterId = clusterId; - dataVersionFilter[i].mDataVersion.SetValue(aDataVersion.Value()); + dataVersionFilter[i].mDataVersion.SetValue(dataVersion); } } @@ -193,7 +205,7 @@ class ReportCommand : public ModelCommand, public chip::app::ReadClient::Callbac params.mIsFabricFiltered = mFabricFiltered.Value(); } - if (aDataVersion.HasValue()) + if (dataVersions.HasValue()) { params.mpDataVersionFilterList = dataVersionFilter; params.mDataVersionFilterListSize = pathsCount; @@ -344,7 +356,7 @@ class ReadAttribute : public ReportCommand private: std::vector mClusterIds; std::vector mAttributeIds; - chip::Optional mDataVersion; + chip::Optional> mDataVersion; }; class SubscribeAttribute : public ReportCommand @@ -425,7 +437,7 @@ class SubscribeAttribute : public ReportCommand uint16_t mMinInterval; uint16_t mMaxInterval; - chip::Optional mDataVersion; + chip::Optional> mDataVersion; bool mWait; }; diff --git a/examples/chip-tool/commands/common/Command.cpp b/examples/chip-tool/commands/common/Command.cpp index e11efe21a920c0..7753234d7905de 100644 --- a/examples/chip-tool/commands/common/Command.cpp +++ b/examples/chip-tool/commands/common/Command.cpp @@ -223,7 +223,7 @@ bool Command::InitArgument(size_t argIndex, char * argValue) vectorArgument->push_back(static_cast(v)); } } - else + else if (arg.type == ArgumentType::Vector32 && arg.flags != Argument::kOptional) { auto vectorArgument = static_cast *>(arg.value); for (uint64_t v : values) @@ -231,6 +231,21 @@ bool Command::InitArgument(size_t argIndex, char * argValue) vectorArgument->push_back(static_cast(v)); } } + else if (arg.type == ArgumentType::Vector32 && arg.flags == Argument::kOptional) + { + std::vector vectorArgument; + for (uint64_t v : values) + { + vectorArgument.push_back(static_cast(v)); + } + + auto optionalArgument = static_cast> *>(arg.value); + optionalArgument->SetValue(vectorArgument); + } + else + { + return false; + } return true; } @@ -557,6 +572,19 @@ size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, std::v return AddArgumentToList(std::move(arg)); } +size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional> * value) +{ + Argument arg; + arg.type = ArgumentType::Vector32; + arg.name = name; + arg.value = static_cast(value); + arg.min = min; + arg.max = max; + arg.flags = Argument::kOptional; + + return AddArgumentToList(std::move(arg)); +} + size_t Command::AddArgument(const char * name, ComplexArgument * value) { Argument arg; diff --git a/examples/chip-tool/commands/common/Command.h b/examples/chip-tool/commands/common/Command.h index 19ae591ed0590e..a9c208770c387e 100644 --- a/examples/chip-tool/commands/common/Command.h +++ b/examples/chip-tool/commands/common/Command.h @@ -174,6 +174,7 @@ class Command size_t AddArgument(const char * name, int64_t min, uint64_t max, std::vector * value); size_t AddArgument(const char * name, int64_t min, uint64_t max, std::vector * value); + size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional> * value); template ::value>> size_t AddArgument(const char * name, int64_t min, uint64_t max, T * out, uint8_t flags = 0)