From 1117406803ecec6bf0e58128b9b6b81182e9a48f Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Fri, 3 Jun 2022 15:56:58 +0200 Subject: [PATCH] [chip-tool] Add support for setting the isUrgent flag of when subscribing to events (#19003) --- .../commands/clusters/ReportCommand.h | 30 ++++++---- .../chip-tool/commands/common/Command.cpp | 55 ++++++++++++++++++- examples/chip-tool/commands/common/Command.h | 3 + .../interaction_model/InteractionModel.cpp | 10 +++- .../interaction_model/InteractionModel.h | 8 ++- 5 files changed, 89 insertions(+), 17 deletions(-) diff --git a/examples/chip-tool/commands/clusters/ReportCommand.h b/examples/chip-tool/commands/clusters/ReportCommand.h index dd533b2fb299d9..5a6bb4bf20c3b3 100644 --- a/examples/chip-tool/commands/clusters/ReportCommand.h +++ b/examples/chip-tool/commands/clusters/ReportCommand.h @@ -350,11 +350,7 @@ class SubscribeEvent : public SubscribeCommand { AddArgument("cluster-id", 0, UINT32_MAX, &mClusterIds); AddArgument("event-id", 0, UINT32_MAX, &mEventIds); - AddArgument("min-interval", 0, UINT16_MAX, &mMinInterval); - AddArgument("max-interval", 0, UINT16_MAX, &mMaxInterval); - AddArgument("fabric-filtered", 0, 1, &mFabricFiltered); - AddArgument("event-min", 0, UINT64_MAX, &mEventNumber); - AddArgument("keepSubscriptions", 0, 1, &mKeepSubscriptions); + AddCommonArguments(); SubscribeCommand::AddArguments(); } @@ -362,11 +358,7 @@ class SubscribeEvent : public SubscribeCommand SubscribeCommand("subscribe-event-by-id", credsIssuerConfig), mClusterIds(1, clusterId) { AddArgument("event-id", 0, UINT32_MAX, &mEventIds); - AddArgument("min-interval", 0, UINT16_MAX, &mMinInterval); - AddArgument("max-interval", 0, UINT16_MAX, &mMaxInterval); - AddArgument("fabric-filtered", 0, 1, &mFabricFiltered); - AddArgument("event-min", 0, UINT64_MAX, &mEventNumber); - AddArgument("keepSubscriptions", 0, 1, &mKeepSubscriptions); + AddCommonArguments(); SubscribeCommand::AddArguments(); } @@ -376,6 +368,12 @@ class SubscribeEvent : public SubscribeCommand mClusterIds(1, clusterId), mEventIds(1, eventId) { AddArgument("event-name", eventName, "Event name."); + AddCommonArguments(); + SubscribeCommand::AddArguments(); + } + + void AddCommonArguments() + { 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, @@ -384,7 +382,14 @@ class SubscribeEvent : public SubscribeCommand 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(); + AddArgument( + "is-urgent", 0, 1, &mIsUrgents, + "Sets isUrgent in the Subscribe Request.\n" + " The queueing of any urgent event SHALL force an immediate generation of reports containing all events queued " + "leading up to (and including) the urgent event in question.\n" + " This argument takes a comma separated list of true/false values.\n" + " If the number of paths exceeds the number of entries provided to is-urgent, then isUrgent will be false for the " + "extra paths."); } ~SubscribeEvent() {} @@ -392,7 +397,7 @@ class SubscribeEvent : public SubscribeCommand CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override { return SubscribeCommand::SubscribeEvent(device, endpointIds, mClusterIds, mEventIds, mMinInterval, mMaxInterval, - mFabricFiltered, mEventNumber, mKeepSubscriptions); + mFabricFiltered, mEventNumber, mKeepSubscriptions, mIsUrgents); } private: @@ -404,4 +409,5 @@ class SubscribeEvent : public SubscribeCommand chip::Optional mFabricFiltered; chip::Optional mEventNumber; chip::Optional mKeepSubscriptions; + chip::Optional> mIsUrgents; }; diff --git a/examples/chip-tool/commands/common/Command.cpp b/examples/chip-tool/commands/common/Command.cpp index a127f913ca8158..f5828f2b138326 100644 --- a/examples/chip-tool/commands/common/Command.cpp +++ b/examples/chip-tool/commands/common/Command.cpp @@ -215,6 +215,39 @@ bool Command::InitArgument(size_t argIndex, char * argValue) return CHIP_NO_ERROR == customArgument->Parse(arg.name, argValue); } + case ArgumentType::VectorBool: { + // Currently only chip::Optional> is supported. + if (arg.flags != Argument::kOptional) + { + return false; + } + + std::vector vectorArgument; + std::stringstream ss(argValue); + while (ss.good()) + { + std::string valueAsString; + getline(ss, valueAsString, ','); + + if (strcasecmp(valueAsString.c_str(), "true") == 0) + { + vectorArgument.push_back(true); + } + else if (strcasecmp(valueAsString.c_str(), "false") == 0) + { + vectorArgument.push_back(false); + } + else + { + return false; + } + } + + auto optionalArgument = static_cast> *>(arg.value); + optionalArgument->SetValue(vectorArgument); + return true; + } + case ArgumentType::Vector16: case ArgumentType::Vector32: { std::vector values; @@ -623,6 +656,21 @@ size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, chip:: return AddArgumentToList(std::move(arg)); } +size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional> * value, + const char * desc) +{ + Argument arg; + arg.type = ArgumentType::VectorBool; + arg.name = name; + arg.value = static_cast(value); + arg.min = min; + arg.max = max; + arg.flags = Argument::kOptional; + arg.desc = desc; + + return AddArgumentToList(std::move(arg)); +} + size_t Command::AddArgument(const char * name, ComplexArgument * value, const char * desc) { Argument arg; @@ -784,7 +832,12 @@ void Command::ResetArguments() const Argument arg = mArgs[i]; const ArgumentType type = arg.type; const uint8_t flags = arg.flags; - if (type == ArgumentType::Vector16 && flags != Argument::kOptional) + if (type == ArgumentType::VectorBool && flags == Argument::kOptional) + { + auto vectorArgument = static_cast *>(arg.value); + vectorArgument->clear(); + } + else if (type == ArgumentType::Vector16 && flags != Argument::kOptional) { auto vectorArgument = static_cast *>(arg.value); vectorArgument->clear(); diff --git a/examples/chip-tool/commands/common/Command.h b/examples/chip-tool/commands/common/Command.h index 0973a9d4fec638..099170b25598b7 100644 --- a/examples/chip-tool/commands/common/Command.h +++ b/examples/chip-tool/commands/common/Command.h @@ -70,6 +70,7 @@ enum ArgumentType Address, Complex, Custom, + VectorBool, Vector16, Vector32, }; @@ -178,6 +179,8 @@ class Command size_t AddArgument(const char * name, int64_t min, uint64_t max, std::vector * value, const char * desc = ""); size_t AddArgument(const char * name, int64_t min, uint64_t max, std::vector * value, const char * desc = ""); + size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional> * value, + const char * desc = ""); size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional> * value, const char * desc = ""); diff --git a/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp b/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp index 2d144ab7f58add..ec3b59078291b4 100644 --- a/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp +++ b/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp @@ -318,15 +318,18 @@ CHIP_ERROR InteractionModelReports::ReportEvent(DeviceProxy * device, std::vecto std::vector clusterIds, std::vector eventIds, ReadClient::InteractionType interactionType, uint16_t minInterval, uint16_t maxInterval, const Optional & fabricFiltered, - const Optional & eventNumber, const Optional & keepSubscriptions) + const Optional & eventNumber, const Optional & keepSubscriptions, + const Optional> & isUrgents) { const size_t clusterCount = clusterIds.size(); const size_t eventCount = eventIds.size(); const size_t endpointCount = endpointIds.size(); + const size_t isUrgentCount = isUrgents.HasValue() ? isUrgents.Value().size() : 0; VerifyOrReturnError(clusterCount > 0 && clusterCount <= kMaxAllowedPaths, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(eventCount > 0 && eventCount <= kMaxAllowedPaths, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(endpointCount > 0 && endpointCount <= kMaxAllowedPaths, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(isUrgentCount <= kMaxAllowedPaths, CHIP_ERROR_INVALID_ARGUMENT); const bool hasSameIdsCount = (clusterCount == eventCount) && (clusterCount == endpointCount); const bool multipleClusters = clusterCount > 1 && eventCount == 1 && endpointCount == 1; @@ -389,6 +392,11 @@ CHIP_ERROR InteractionModelReports::ReportEvent(DeviceProxy * device, std::vecto { eventPathParams[i].mEndpointId = endpointId; } + + if (isUrgents.HasValue() && isUrgents.Value().size() > i) + { + eventPathParams[i].mIsUrgentEvent = isUrgents.Value().at(i); + } } ReadPrepareParams params(device->GetSecureSession().Value()); diff --git a/src/app/tests/suites/commands/interaction_model/InteractionModel.h b/src/app/tests/suites/commands/interaction_model/InteractionModel.h index 7ce5e03c398c7d..e3392b1f9bb59c 100644 --- a/src/app/tests/suites/commands/interaction_model/InteractionModel.h +++ b/src/app/tests/suites/commands/interaction_model/InteractionModel.h @@ -76,10 +76,11 @@ class InteractionModelReports 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) + const chip::Optional & keepSubscriptions = chip::NullOptional, + const chip::Optional> & isUrgents = chip::NullOptional) { return ReportEvent(device, endpointIds, clusterIds, eventIds, chip::app::ReadClient::InteractionType::Subscribe, - minInterval, maxInterval, fabricFiltered, eventNumber, keepSubscriptions); + minInterval, maxInterval, fabricFiltered, eventNumber, keepSubscriptions, isUrgents); } CHIP_ERROR ReportEvent(chip::DeviceProxy * device, std::vector endpointIds, @@ -87,7 +88,8 @@ class InteractionModelReports chip::app::ReadClient::InteractionType interactionType, 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); + const chip::Optional & keepSubscriptions = chip::NullOptional, + const chip::Optional> & isUrgents = chip::NullOptional); void Shutdown() { mReadClients.clear(); }