diff --git a/examples/chip-tool/BUILD.gn b/examples/chip-tool/BUILD.gn index 2da0372fef7458..fbe554ed741318 100644 --- a/examples/chip-tool/BUILD.gn +++ b/examples/chip-tool/BUILD.gn @@ -30,6 +30,7 @@ config("config") { ] defines = [ + "CONFIG_USE_LOCAL_STORAGE=${config_use_local_storage}", "CONFIG_USE_SEPARATE_EVENTLOOP=${config_use_separate_eventloop}", "CONFIG_USE_INTERACTIVE_MODE=${config_use_interactive_mode}", "CONFIG_ENABLE_YAML_TESTS=${config_enable_yaml_tests}", @@ -49,10 +50,13 @@ static_library("chip-tool-utils") { "${chip_root}/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp", "${chip_root}/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp", "commands/clusters/ModelCommand.cpp", + "commands/clusters/ModelCommand.h", "commands/common/CHIPCommand.cpp", "commands/common/CHIPCommand.h", "commands/common/Command.cpp", + "commands/common/Command.h", "commands/common/Commands.cpp", + "commands/common/Commands.h", "commands/common/CredentialIssuerCommands.h", "commands/discover/DiscoverCommand.cpp", "commands/discover/DiscoverCommissionablesCommand.cpp", diff --git a/examples/chip-tool/chip-tool.gni b/examples/chip-tool/chip-tool.gni index 4e607dcdd7d6a0..b85f1f32340ed5 100644 --- a/examples/chip-tool/chip-tool.gni +++ b/examples/chip-tool/chip-tool.gni @@ -20,4 +20,5 @@ declare_args() { config_use_separate_eventloop = true config_use_interactive_mode = true config_enable_yaml_tests = true + config_use_local_storage = true } diff --git a/examples/chip-tool/commands/clusters/ModelCommand.h b/examples/chip-tool/commands/clusters/ModelCommand.h index b6fa961bff756d..4a0c2c08f5d469 100644 --- a/examples/chip-tool/commands/clusters/ModelCommand.h +++ b/examples/chip-tool/commands/clusters/ModelCommand.h @@ -18,7 +18,10 @@ #pragma once +#ifdef CONFIG_USE_LOCAL_STORAGE #include "../../config/PersistentStorage.h" +#endif // CONFIG_USE_LOCAL_STORAGE + #include "../common/CHIPCommand.h" #include diff --git a/examples/chip-tool/commands/clusters/SubscriptionsCommands.h b/examples/chip-tool/commands/clusters/SubscriptionsCommands.h index effc9f4edca2b6..207127a39b1031 100644 --- a/examples/chip-tool/commands/clusters/SubscriptionsCommands.h +++ b/examples/chip-tool/commands/clusters/SubscriptionsCommands.h @@ -18,6 +18,11 @@ #pragma once +#include + +#include +#include + class ShutdownSubscription : public CHIPCommand { public: diff --git a/examples/chip-tool/commands/common/CHIPCommand.h b/examples/chip-tool/commands/common/CHIPCommand.h index 1313fadeb1f664..e484260a3a4fb1 100644 --- a/examples/chip-tool/commands/common/CHIPCommand.h +++ b/examples/chip-tool/commands/common/CHIPCommand.h @@ -18,8 +18,12 @@ #pragma once +#ifdef CONFIG_USE_LOCAL_STORAGE #include "../../config/PersistentStorage.h" +#endif // CONFIG_USE_LOCAL_STORAGE + #include "Command.h" + #include #include #include @@ -27,8 +31,6 @@ #pragma once -class PersistentStorage; - constexpr const char kIdentityAlpha[] = "alpha"; constexpr const char kIdentityBeta[] = "beta"; constexpr const char kIdentityGamma[] = "gamma"; @@ -114,8 +116,10 @@ class CHIPCommand : public Command // Execute any deferred cleanups. Used when exiting interactive mode. void ExecuteDeferredCleanups(); +#ifdef CONFIG_USE_LOCAL_STORAGE PersistentStorage mDefaultStorage; PersistentStorage mCommissionerStorage; +#endif // CONFIG_USE_LOCAL_STORAGE chip::PersistentStorageOperationalKeystore mOperationalKeystore; chip::Credentials::GroupDataProviderImpl mGroupDataProvider{ kMaxGroupsPerFabric, kMaxGroupKeysPerFabric }; diff --git a/examples/chip-tool/commands/common/Commands.cpp b/examples/chip-tool/commands/common/Commands.cpp index 131e66f1c8aa3e..b7bd6f03db466f 100644 --- a/examples/chip-tool/commands/common/Commands.cpp +++ b/examples/chip-tool/commands/common/Commands.cpp @@ -41,10 +41,12 @@ int Commands::Run(int argc, char ** argv) err = chip::Platform::MemoryInit(); VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init Memory failure: %s", chip::ErrorStr(err))); +#ifdef CONFIG_USE_LOCAL_STORAGE err = mStorage.Init(); VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init Storage failure: %s", chip::ErrorStr(err))); chip::Logging::SetLogFilter(mStorage.GetLoggingLevel()); +#endif // CONFIG_USE_LOCAL_STORAGE err = RunCommand(argc, argv); VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(chipTool, "Run command failure: %s", chip::ErrorStr(err))); diff --git a/examples/chip-tool/commands/common/Commands.h b/examples/chip-tool/commands/common/Commands.h index e70a942779c9e1..a39c984954777e 100644 --- a/examples/chip-tool/commands/common/Commands.h +++ b/examples/chip-tool/commands/common/Commands.h @@ -18,7 +18,10 @@ #pragma once +#ifdef CONFIG_USE_LOCAL_STORAGE #include "../../config/PersistentStorage.h" +#endif // CONFIG_USE_LOCAL_STORAGE + #include "Command.h" #include @@ -48,5 +51,7 @@ class Commands void ShowCommand(std::string executable, std::string clusterName, Command * command); std::map mClusters; +#ifdef CONFIG_USE_LOCAL_STORAGE PersistentStorage mStorage; +#endif // CONFIG_USE_LOCAL_STORAGE }; diff --git a/examples/tv-casting-app/tv-casting-common/BUILD.gn b/examples/tv-casting-app/tv-casting-common/BUILD.gn index 10ef81c9104434..fc3135ab8d263a 100644 --- a/examples/tv-casting-app/tv-casting-common/BUILD.gn +++ b/examples/tv-casting-app/tv-casting-common/BUILD.gn @@ -20,6 +20,7 @@ import("${chip_root}/src/lib/lib.gni") config("config") { include_dirs = [ ".", + "${chip_root}/examples/chip-tool", "${chip_root}/zzz_generated/chip-tool", "${chip_root}/zzz_generated/tv-casting-app", "${chip_root}/src/lib", @@ -35,14 +36,17 @@ chip_data_model("tv-casting-common") { "${chip_root}/zzz_generated/tv-casting-app/zap-generated" sources = [ + "${chip_root}/examples/chip-tool/commands/clusters/ModelCommand.h", + "${chip_root}/examples/chip-tool/commands/common/CHIPCommand.h", + "${chip_root}/examples/chip-tool/commands/common/Command.cpp", + "${chip_root}/examples/chip-tool/commands/common/Command.h", + "${chip_root}/examples/chip-tool/commands/common/Commands.cpp", + "${chip_root}/examples/chip-tool/commands/common/Commands.h", + "${chip_root}/examples/chip-tool/commands/common/CredentialIssuerCommands.h", "${chip_root}/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp", "${chip_root}/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp", "commands/clusters/ModelCommand.cpp", "commands/common/CHIPCommand.cpp", - "commands/common/CHIPCommand.h", - "commands/common/Command.cpp", - "commands/common/Commands.cpp", - "commands/common/CredentialIssuerCommands.h", "include/CastingServer.h", "include/TargetEndpointInfo.h", "include/TargetVideoPlayerInfo.h", @@ -51,7 +55,10 @@ chip_data_model("tv-casting-common") { "src/TargetVideoPlayerInfo.cpp", ] - deps = [ "${chip_root}/third_party/jsoncpp" ] + deps = [ + "${chip_root}/src/app/tests/suites/commands/interaction_model", + "${chip_root}/third_party/jsoncpp", + ] if (chip_enable_transport_trace) { public_deps = diff --git a/examples/tv-casting-app/tv-casting-common/commands/clusters/ClusterCommand.h b/examples/tv-casting-app/tv-casting-common/commands/clusters/ClusterCommand.h deleted file mode 100644 index 24db51b5d1b4d9..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/clusters/ClusterCommand.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -#include -#include - -#include "DataModelLogger.h" -#include "ModelCommand.h" - -class ClusterCommand : public ModelCommand, public chip::app::CommandSender::Callback -{ -public: - ClusterCommand(CredentialIssuerCommands * credsIssuerConfig) : ModelCommand("command-by-id", credsIssuerConfig) - { - AddArgument("cluster-id", 0, UINT32_MAX, &mClusterId); - AddArgument("command-id", 0, UINT32_MAX, &mCommandId); - AddArgument("payload", &mPayload); - AddArgument("timedInteractionTimeoutMs", 0, UINT16_MAX, &mTimedInteractionTimeoutMs); - AddArgument("suppressResponse", 0, 1, &mSuppressResponse); - AddArgument("repeat-count", 1, UINT16_MAX, &mRepeatCount); - AddArgument("repeat-delay-ms", 0, UINT16_MAX, &mRepeatDelayInMs); - ModelCommand::AddArguments(); - } - - ClusterCommand(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) : - ModelCommand("command-by-id", credsIssuerConfig), mClusterId(clusterId) - { - AddArgument("command-id", 0, UINT32_MAX, &mCommandId); - AddArgument("payload", &mPayload); - AddArgument("timedInteractionTimeoutMs", 0, UINT16_MAX, &mTimedInteractionTimeoutMs); - AddArgument("suppressResponse", 0, 1, &mSuppressResponse); - AddArgument("repeat-count", 1, UINT16_MAX, &mRepeatCount); - AddArgument("repeat-delay-ms", 0, UINT16_MAX, &mRepeatDelayInMs); - ModelCommand::AddArguments(); - } - - ClusterCommand(const char * commandName, CredentialIssuerCommands * credsIssuerConfig) : - ModelCommand(commandName, credsIssuerConfig) - { - AddArgument("timedInteractionTimeoutMs", 0, UINT16_MAX, &mTimedInteractionTimeoutMs); - AddArgument("suppressResponse", 0, 1, &mSuppressResponse); - AddArgument("repeat-count", 1, UINT16_MAX, &mRepeatCount); - AddArgument("repeat-delay-ms", 0, UINT16_MAX, &mRepeatDelayInMs); - } - - ~ClusterCommand() {} - - CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override - { - return ClusterCommand::SendCommand(device, endpointIds.at(0), mClusterId, mCommandId, mPayload); - } - - CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override - { - return ClusterCommand::SendGroupCommand(groupId, fabricIndex, mClusterId, mCommandId, mPayload); - } - - /////////// CommandSender Callback Interface ///////// - virtual void OnResponse(chip::app::CommandSender * client, const chip::app::ConcreteCommandPath & path, - const chip::app::StatusIB & status, chip::TLV::TLVReader * data) override - { - CHIP_ERROR error = status.ToChipError(); - if (CHIP_NO_ERROR != error) - { - ChipLogError(chipTool, "Response Failure: %s", chip::ErrorStr(error)); - mError = error; - return; - } - - if (data != nullptr) - { - error = DataModelLogger::LogCommand(path, data); - if (CHIP_NO_ERROR != error) - { - ChipLogError(chipTool, "Response Failure: Can not decode Data"); - mError = error; - return; - } - } - } - - virtual void OnError(const chip::app::CommandSender * client, CHIP_ERROR error) override - { - ChipLogProgress(chipTool, "Error: %s", chip::ErrorStr(error)); - mError = error; - } - - virtual void OnDone(chip::app::CommandSender * client) override - { - mCommandSender.front().reset(); - mCommandSender.erase(mCommandSender.begin()); - - // If the command is repeated N times, wait for all the responses to comes in - // before exiting. - bool shouldStop = true; - if (mRepeatCount.HasValue()) - { - mRepeatCount.SetValue(static_cast(mRepeatCount.Value() - 1)); - shouldStop = mRepeatCount.Value() == 0; - } - - if (shouldStop) - { - SetCommandExitStatus(mError); - } - } - - template - CHIP_ERROR SendCommand(chip::DeviceProxy * device, chip::EndpointId endpointId, chip::ClusterId clusterId, - chip::CommandId commandId, const T & value) - { - uint16_t repeatCount = mRepeatCount.ValueOr(1); - while (repeatCount--) - { - chip::app::CommandPathParams commandPath = { endpointId, 0 /* groupId */, clusterId, commandId, - (chip::app::CommandPathFlags::kEndpointIdValid) }; - - auto commandSender = std::make_unique(this, device->GetExchangeManager(), - mTimedInteractionTimeoutMs.HasValue()); - VerifyOrReturnError(commandSender != nullptr, CHIP_ERROR_NO_MEMORY); - ReturnErrorOnFailure(commandSender->AddRequestDataNoTimedCheck(commandPath, value, mTimedInteractionTimeoutMs, - mSuppressResponse.ValueOr(false))); - - ReturnErrorOnFailure(commandSender->SendCommandRequest(device->GetSecureSession().Value())); - mCommandSender.push_back(std::move(commandSender)); - - if (mRepeatDelayInMs.HasValue()) - { - chip::test_utils::SleepMillis(mRepeatDelayInMs.Value()); - } - } - return CHIP_NO_ERROR; - } - - template - CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex, chip::ClusterId clusterId, - chip::CommandId commandId, const T & value) - { - chip::app::CommandPathParams commandPath = { 0 /* endpoint */, groupId, clusterId, commandId, - (chip::app::CommandPathFlags::kGroupIdValid) }; - - chip::Messaging::ExchangeManager * exchangeManager = chip::app::InteractionModelEngine::GetInstance()->GetExchangeManager(); - - auto commandSender = - chip::Platform::MakeUnique(this, exchangeManager, mTimedInteractionTimeoutMs.HasValue()); - VerifyOrReturnError(commandSender != nullptr, CHIP_ERROR_NO_MEMORY); - ReturnErrorOnFailure(commandSender->AddRequestDataNoTimedCheck(commandPath, value, mTimedInteractionTimeoutMs)); - - chip::Transport::OutgoingGroupSession session(groupId, fabricIndex); - ReturnErrorOnFailure(commandSender->SendGroupCommandRequest(chip::SessionHandle(session))); - commandSender.release(); - - return CHIP_NO_ERROR; - } - -private: - chip::ClusterId mClusterId; - chip::CommandId mCommandId; - chip::Optional mTimedInteractionTimeoutMs; - chip::Optional mSuppressResponse; - chip::Optional mRepeatCount; - chip::Optional mRepeatDelayInMs; - - CHIP_ERROR mError = CHIP_NO_ERROR; - CustomArgument mPayload; - std::vector> mCommandSender; -}; diff --git a/examples/tv-casting-app/tv-casting-common/commands/clusters/ComplexArgument.h b/examples/tv-casting-app/tv-casting-common/commands/clusters/ComplexArgument.h deleted file mode 100644 index aafc18d68d7591..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/clusters/ComplexArgument.h +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -constexpr uint8_t kMaxLabelLength = 100; - -class ComplexArgumentParser -{ -public: - ComplexArgumentParser() {} - - template ::value && !std::is_signed::value && - !std::is_same>, bool>::value, - int> = 0> - static CHIP_ERROR Setup(const char * label, T & request, Json::Value value) - { - if (value.isNumeric()) - { - if (chip::CanCastTo(value.asLargestUInt())) - { - request = static_cast(value.asLargestUInt()); - return CHIP_NO_ERROR; - } - } - else if (value.isString()) - { - // Check for a hex number; JSON does not support those as numbers, - // so they have to be done as strings. And we might as well support - // string-encoded unsigned numbers in general if we're doing that. - bool isHexNotation = strncmp(value.asCString(), "0x", 2) == 0 || strncmp(value.asCString(), "0X", 2) == 0; - - std::stringstream str; - isHexNotation ? str << std::hex << value.asCString() : str << value.asCString(); - uint64_t val; - str >> val; - if (!str.fail() && str.eof() && chip::CanCastTo(val)) - { - request = static_cast(val); - return CHIP_NO_ERROR; - } - } - - ChipLogError(chipTool, "Error while encoding %s as an unsigned integer.", label); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - template ::value, bool> = true> - static CHIP_ERROR Setup(const char * label, T & request, Json::Value value) - { - if (!value.isNumeric() || !chip::CanCastTo(value.asLargestInt())) - { - ChipLogError(chipTool, "Error while encoding %s as an unsigned integer.", label); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - request = static_cast(value.asLargestInt()); - return CHIP_NO_ERROR; - } - - template ::value, int> = 0> - static CHIP_ERROR Setup(const char * label, T & request, Json::Value value) - { - std::underlying_type_t requestValue; - ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value)); - - request = static_cast(requestValue); - return CHIP_NO_ERROR; - } - - template - static CHIP_ERROR Setup(const char * label, chip::BitFlags & request, Json::Value & value) - { - T requestValue; - ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value)); - - request = chip::BitFlags(requestValue); - return CHIP_NO_ERROR; - } - - template - static CHIP_ERROR Setup(const char * label, chip::Optional & request, Json::Value & value) - { - T requestValue; - ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value)); - - request = chip::Optional(requestValue); - return CHIP_NO_ERROR; - } - - template - static CHIP_ERROR Setup(const char * label, chip::app::DataModel::Nullable & request, Json::Value & value) - { - if (value.isNull()) - { - request.SetNull(); - return CHIP_NO_ERROR; - } - - T requestValue; - ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value)); - - request = chip::app::DataModel::Nullable(requestValue); - return CHIP_NO_ERROR; - } - - template - static CHIP_ERROR Setup(const char * label, chip::app::DataModel::List & request, Json::Value & value) - { - if (!value.isArray()) - { - ChipLogError(chipTool, "Error while encoding %s as an array.", label); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - auto content = static_cast::type *>(chip::Platform::MemoryCalloc(value.size(), sizeof(T))); - - Json::ArrayIndex size = value.size(); - for (Json::ArrayIndex i = 0; i < size; i++) - { - char labelWithIndex[kMaxLabelLength]; - snprintf(labelWithIndex, sizeof(labelWithIndex), "%s[%d]", label, i); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithIndex, content[i], value[i])); - } - - request = chip::app::DataModel::List(content, value.size()); - return CHIP_NO_ERROR; - } - - static CHIP_ERROR Setup(const char * label, chip::ByteSpan & request, Json::Value & value) - { - if (!value.isString()) - { - ChipLogError(chipTool, "Error while encoding %s as an octet string: Not a string.", label); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - if (strlen(value.asCString()) % 2 != 0) - { - ChipLogError(chipTool, "Error while encoding %s as an octet string: Odd number of characters.", label); - return CHIP_ERROR_INVALID_STRING_LENGTH; - } - - size_t size = strlen(value.asCString()); - auto buffer = static_cast(chip::Platform::MemoryCalloc(size / 2, sizeof(uint8_t))); - size_t octetCount = chip::Encoding::HexToBytes(value.asCString(), size, buffer, size / 2); - - request = chip::ByteSpan(buffer, octetCount); - return CHIP_NO_ERROR; - } - - static CHIP_ERROR Setup(const char * label, chip::CharSpan & request, Json::Value & value) - { - if (!value.isString()) - { - ChipLogError(chipTool, "Error while encoding %s as a string: Not a string.", label); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - size_t size = strlen(value.asCString()); - auto buffer = static_cast(chip::Platform::MemoryCalloc(size, sizeof(char))); - strncpy(buffer, value.asCString(), size); - - request = chip::CharSpan(buffer, size); - return CHIP_NO_ERROR; - } - - static CHIP_ERROR Setup(const char * label, float & request, Json::Value & value) - { - if (!value.isNumeric()) - { - ChipLogError(chipTool, "Error while encoding %s as a float: Not a number.", label); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - request = static_cast(value.asFloat()); - return CHIP_NO_ERROR; - } - - static CHIP_ERROR Setup(const char * label, double & request, Json::Value & value) - { - if (!value.isNumeric()) - { - ChipLogError(chipTool, "Error while encoding %s as a double: Not a number.", label); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - request = static_cast(value.asDouble()); - return CHIP_NO_ERROR; - } - - static CHIP_ERROR Setup(const char * label, bool & request, Json::Value & value) - { - if (!value.isBool()) - { - ChipLogError(chipTool, "Error while encoding %s as a boolean: Not a boolean.", label); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - request = value.asBool(); - return CHIP_NO_ERROR; - } - - static CHIP_ERROR EnsureMemberExist(const char * label, const char * memberName, bool hasMember) - { - if (hasMember) - { - return CHIP_NO_ERROR; - } - - ChipLogError(chipTool, "%s is required. Should be provided as {\"%s\": value}", label, memberName); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - template - static void Finalize(T & request) - { - // Nothing to do - } - - template - static void Finalize(chip::Optional & request) - { - VerifyOrReturn(request.HasValue()); - ComplexArgumentParser::Finalize(request.Value()); - } - - template - static void Finalize(chip::app::DataModel::Nullable & request) - { - VerifyOrReturn(!request.IsNull()); - ComplexArgumentParser::Finalize(request.Value()); - } - - static void Finalize(chip::ByteSpan & request) - { - VerifyOrReturn(request.data() != nullptr); - chip::Platform::MemoryFree(reinterpret_cast(const_cast(request.data()))); - } - - static void Finalize(chip::CharSpan & request) - { - VerifyOrReturn(request.data() != nullptr); - chip::Platform::MemoryFree(reinterpret_cast(const_cast(request.data()))); - } - - template - static void Finalize(chip::app::DataModel::List & request) - { - VerifyOrReturn(request.data() != nullptr); - - size_t size = request.size(); - auto data = const_cast::type *>(request.data()); - for (size_t i = 0; i < size; i++) - { - Finalize(data[i]); - } - - chip::Platform::MemoryFree(reinterpret_cast(data)); - } - -#include -}; - -class ComplexArgument -{ -public: - virtual ~ComplexArgument() {} - - virtual CHIP_ERROR Parse(const char * label, const char * json) = 0; -}; - -template -class TypedComplexArgument : public ComplexArgument -{ -public: - TypedComplexArgument(T * request) : mRequest(request) {} - ~TypedComplexArgument() { ComplexArgumentParser::Finalize(*mRequest); } - - CHIP_ERROR Parse(const char * label, const char * json) - { - Json::Value value; - Json::Reader reader; - if (!reader.parse(json, value)) - { - std::vector errors = reader.getStructuredErrors(); - ChipLogError(chipTool, "Error parsing JSON for %s:", label); - for (auto & error : errors) - { - ChipLogError(chipTool, " %s", error.message.c_str()); - ptrdiff_t error_start = error.offset_start; - ptrdiff_t error_end = error.offset_limit; - const char * sourceText = json; - // The whole JSON string might be too long to fit in our log - // messages. Just include 30 chars before the error. - constexpr ptrdiff_t kMaxContext = 30; - std::string errorMsg; - if (error_start > kMaxContext) - { - sourceText += (error_start - kMaxContext); - error_end = kMaxContext + (error_end - error_start); - error_start = kMaxContext; - ChipLogError(chipTool, "... %s", sourceText); - // Add markers corresponding to the "... " above. - errorMsg += "----"; - } - else - { - ChipLogError(chipTool, "%s", sourceText); - } - for (ptrdiff_t i = 0; i < error_start; ++i) - { - errorMsg += "-"; - } - errorMsg += "^"; - if (error_start + 1 < error_end) - { - for (ptrdiff_t i = error_start + 1; i < error_end; ++i) - { - errorMsg += "-"; - } - errorMsg += "^"; - } - ChipLogError(chipTool, "%s", errorMsg.c_str()); - - if (error.message == "Missing ',' or '}' in object declaration" && error.offset_start > 0 && - json[error.offset_start - 1] == '0' && (json[error.offset_start] == 'x' || json[error.offset_start] == 'X')) - { - ChipLogError(chipTool, - "NOTE: JSON does not allow hex syntax beginning with 0x for numbers. Try putting the hex number " - "in quotes (like {\"name\": \"0x100\"})."); - } - } - return CHIP_ERROR_INVALID_ARGUMENT; - } - - return ComplexArgumentParser::Setup(label, *mRequest, value); - } - -private: - T * mRequest; -}; diff --git a/examples/tv-casting-app/tv-casting-common/commands/clusters/CustomArgument.h b/examples/tv-casting-app/tv-casting-common/commands/clusters/CustomArgument.h deleted file mode 100644 index 2362171aa06da9..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/clusters/CustomArgument.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -#include -#include -#include - -namespace { -static constexpr char kPayloadHexPrefix[] = "hex:"; -static constexpr char kPayloadSignedPrefix[] = "s:"; -static constexpr char kPayloadUnsignedPrefix[] = "u:"; -static constexpr char kPayloadFloatPrefix[] = "f:"; -static constexpr char kPayloadDoublePrefix[] = "d:"; -static constexpr size_t kPayloadHexPrefixLen = ArraySize(kPayloadHexPrefix) - 1; // ignore null character -static constexpr size_t kPayloadSignedPrefixLen = ArraySize(kPayloadSignedPrefix) - 1; // ignore null character -static constexpr size_t kPayloadUnsignedPrefixLen = ArraySize(kPayloadUnsignedPrefix) - 1; // ignore null character -static constexpr size_t kPayloadFloatPrefixLen = ArraySize(kPayloadFloatPrefix) - 1; // ignore null character -static constexpr size_t kPayloadDoublePrefixLen = ArraySize(kPayloadDoublePrefix) - 1; // ignore null character -} // namespace - -class CustomArgumentParser -{ -public: - static CHIP_ERROR Put(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value) - { - if (value.isObject()) - { - return CustomArgumentParser::PutObject(writer, tag, value); - } - - if (value.isArray()) - { - return CustomArgumentParser::PutArray(writer, tag, value); - } - - if (value.isString()) - { - if (IsOctetString(value)) - { - return CustomArgumentParser::PutOctetString(writer, tag, value); - } - if (IsUnsignedNumberPrefix(value)) - { - return CustomArgumentParser::PutUnsignedFromString(writer, tag, value); - } - if (IsSignedNumberPrefix(value)) - { - return CustomArgumentParser::PutSignedFromString(writer, tag, value); - } - if (IsFloatNumberPrefix(value)) - { - return CustomArgumentParser::PutFloatFromString(writer, tag, value); - } - if (IsDoubleNumberPrefix(value)) - { - return CustomArgumentParser::PutDoubleFromString(writer, tag, value); - } - - return CustomArgumentParser::PutCharString(writer, tag, value); - } - - if (value.isNull()) - { - return chip::app::DataModel::Encode(*writer, tag, chip::app::DataModel::Nullable()); - } - - if (value.isBool()) - { - return chip::app::DataModel::Encode(*writer, tag, value.asBool()); - } - - if (value.isUInt()) - { - return chip::app::DataModel::Encode(*writer, tag, value.asLargestUInt()); - } - - if (value.isInt()) - { - return chip::app::DataModel::Encode(*writer, tag, value.asLargestInt()); - } - - if (value.isNumeric()) - { - return chip::app::DataModel::Encode(*writer, tag, value.asDouble()); - } - - return CHIP_ERROR_NOT_IMPLEMENTED; - } - -private: - static CHIP_ERROR PutArray(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value) - { - chip::TLV::TLVType outer; - ReturnErrorOnFailure(writer->StartContainer(tag, chip::TLV::kTLVType_Array, outer)); - - Json::ArrayIndex size = value.size(); - - for (Json::ArrayIndex i = 0; i < size; i++) - { - ReturnErrorOnFailure(CustomArgumentParser::Put(writer, chip::TLV::AnonymousTag(), value[i])); - } - - return writer->EndContainer(outer); - } - - static CHIP_ERROR PutObject(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value) - { - chip::TLV::TLVType outer; - ReturnErrorOnFailure(writer->StartContainer(tag, chip::TLV::kTLVType_Structure, outer)); - - for (auto const & id : value.getMemberNames()) - { - auto index = std::stoul(id, nullptr, 0); - VerifyOrReturnError(chip::CanCastTo(index), CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorOnFailure(CustomArgumentParser::Put(writer, chip::TLV::ContextTag(static_cast(index)), value[id])); - } - - return writer->EndContainer(outer); - } - - static CHIP_ERROR PutOctetString(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value) - { - size_t size = strlen(value.asCString()); - VerifyOrReturnError(size % 2 == 0, CHIP_ERROR_INVALID_STRING_LENGTH); - - chip::Platform::ScopedMemoryBuffer buffer; - VerifyOrReturnError(buffer.Calloc(size / 2), CHIP_ERROR_NO_MEMORY); - size_t octetCount = chip::Encoding::HexToBytes(value.asCString() + kPayloadHexPrefixLen, size - kPayloadHexPrefixLen, - buffer.Get(), (size - kPayloadHexPrefixLen) / 2); - VerifyOrReturnError(octetCount != 0, CHIP_ERROR_NO_MEMORY); - - return chip::app::DataModel::Encode(*writer, tag, chip::ByteSpan(buffer.Get(), octetCount)); - } - - static CHIP_ERROR PutCharString(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value) - { - size_t size = strlen(value.asCString()); - return chip::app::DataModel::Encode(*writer, tag, chip::CharSpan(value.asCString(), size)); - } - - static CHIP_ERROR PutUnsignedFromString(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value) - { - char numberAsString[21]; - chip::Platform::CopyString(numberAsString, value.asCString() + kPayloadUnsignedPrefixLen); - - auto number = std::stoull(numberAsString, nullptr, 0); - return chip::app::DataModel::Encode(*writer, tag, static_cast(number)); - } - - static CHIP_ERROR PutSignedFromString(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value) - { - char numberAsString[21]; - chip::Platform::CopyString(numberAsString, value.asCString() + kPayloadSignedPrefixLen); - - auto number = std::stoll(numberAsString, nullptr, 0); - return chip::app::DataModel::Encode(*writer, tag, static_cast(number)); - } - - static CHIP_ERROR PutFloatFromString(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value) - { - char numberAsString[21]; - chip::Platform::CopyString(numberAsString, value.asCString() + kPayloadFloatPrefixLen); - - auto number = std::stof(numberAsString); - return chip::app::DataModel::Encode(*writer, tag, number); - } - - static CHIP_ERROR PutDoubleFromString(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value) - { - char numberAsString[21]; - chip::Platform::CopyString(numberAsString, value.asCString() + kPayloadDoublePrefixLen); - - auto number = std::stod(numberAsString); - return chip::app::DataModel::Encode(*writer, tag, number); - } - - static bool IsOctetString(Json::Value & value) - { - return (strncmp(value.asCString(), kPayloadHexPrefix, kPayloadHexPrefixLen) == 0); - } - - static bool IsUnsignedNumberPrefix(Json::Value & value) - { - return (strncmp(value.asCString(), kPayloadUnsignedPrefix, kPayloadUnsignedPrefixLen) == 0); - } - - static bool IsSignedNumberPrefix(Json::Value & value) - { - return (strncmp(value.asCString(), kPayloadSignedPrefix, kPayloadSignedPrefixLen) == 0); - } - - static bool IsFloatNumberPrefix(Json::Value & value) - { - return (strncmp(value.asCString(), kPayloadFloatPrefix, kPayloadFloatPrefixLen) == 0); - } - - static bool IsDoubleNumberPrefix(Json::Value & value) - { - return (strncmp(value.asCString(), kPayloadDoublePrefix, kPayloadDoublePrefixLen) == 0); - } -}; - -class CustomArgument -{ -public: - ~CustomArgument() - { - if (mData != nullptr) - { - chip::Platform::MemoryFree(mData); - } - } - - CHIP_ERROR Parse(const char * label, const char * json) - { - Json::Reader reader; - Json::Value value; - reader.parse(json, value); - - mData = static_cast(chip::Platform::MemoryCalloc(sizeof(uint8_t), mDataMaxLen)); - VerifyOrReturnError(mData != nullptr, CHIP_ERROR_NO_MEMORY); - - chip::TLV::TLVWriter writer; - writer.Init(mData, mDataMaxLen); - - ReturnErrorOnFailure(CustomArgumentParser::Put(&writer, chip::TLV::AnonymousTag(), value)); - - mDataLen = writer.GetLengthWritten(); - return writer.Finalize(); - } - - CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const - { - chip::TLV::TLVReader reader; - reader.Init(mData, mDataLen); - reader.Next(); - - return writer.CopyElement(tag, reader); - } - - // We trust our consumers to do the encoding of our data correctly, so don't - // need to know whether we are being encoded for a write. - static constexpr bool kIsFabricScoped = false; - -private: - uint8_t * mData = nullptr; - uint32_t mDataLen = 0; - static constexpr uint32_t mDataMaxLen = 4096; -}; diff --git a/examples/tv-casting-app/tv-casting-common/commands/clusters/DataModelLogger.h b/examples/tv-casting-app/tv-casting-common/commands/clusters/DataModelLogger.h deleted file mode 100644 index 7d725cf0a8b5ab..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/clusters/DataModelLogger.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -#include - -#include -#include -#include -#include -#include -#include - -class DataModelLogger -{ -public: - static CHIP_ERROR LogAttribute(const chip::app::ConcreteDataAttributePath & path, chip::TLV::TLVReader * data); - static CHIP_ERROR LogCommand(const chip::app::ConcreteCommandPath & path, chip::TLV::TLVReader * data); - static CHIP_ERROR LogEvent(const chip::app::EventHeader & header, chip::TLV::TLVReader * data); - -private: - static CHIP_ERROR LogValue(const char * label, size_t indent, bool value) - { - DataModelLogger::LogString(label, indent, value ? "TRUE" : "FALSE"); - return CHIP_NO_ERROR; - } - - static CHIP_ERROR LogValue(const char * label, size_t indent, chip::CharSpan value) - { - DataModelLogger::LogString(label, indent, std::string(value.data(), value.size())); - return CHIP_NO_ERROR; - } - - static CHIP_ERROR LogValue(const char * label, size_t indent, chip::ByteSpan value) - { - char buffer[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE]; - if (CHIP_NO_ERROR == - chip::Encoding::BytesToUppercaseHexString(value.data(), value.size(), &buffer[0], CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE)) - { - DataModelLogger::LogString(label, indent, buffer); - } - else - { - DataModelLogger::LogString(label, indent, - std::string("Elided value too large of size ") + std::to_string(value.size())); - } - - return CHIP_NO_ERROR; - } - - template ::value && !std::is_same>, bool>::value, int> = 0> - static CHIP_ERROR LogValue(const char * label, size_t indent, X value) - { - DataModelLogger::LogString(label, indent, std::to_string(value)); - return CHIP_NO_ERROR; - } - - template ::value, int> = 0> - static CHIP_ERROR LogValue(const char * label, size_t indent, X value) - { - DataModelLogger::LogString(label, indent, std::to_string(value)); - return CHIP_NO_ERROR; - } - - template ::value, int> = 0> - static CHIP_ERROR LogValue(const char * label, size_t indent, X value) - { - DataModelLogger::LogValue(label, indent, chip::to_underlying(value)); - return CHIP_NO_ERROR; - } - - template - static CHIP_ERROR LogValue(const char * label, size_t indent, chip::BitFlags value) - { - DataModelLogger::LogValue(label, indent, value.Raw()); - return CHIP_NO_ERROR; - } - - template - static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::DataModel::DecodableList & value) - { - size_t count = 0; - CHIP_ERROR err = value.ComputeSize(&count); - if (err != CHIP_NO_ERROR) - { - return err; - } - DataModelLogger::LogString(label, indent, std::to_string(count) + " entries"); - - auto iter = value.begin(); - size_t i = 0; - while (iter.Next()) - { - ++i; - std::string itemLabel = std::string("[") + std::to_string(i) + "]"; - ReturnErrorOnFailure(DataModelLogger::LogValue(itemLabel.c_str(), indent + 1, iter.GetValue())); - } - if (iter.GetStatus() != CHIP_NO_ERROR) - { - DataModelLogger::LogString(indent + 1, "List truncated due to invalid value"); - } - return iter.GetStatus(); - } - - template - static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::DataModel::Nullable & value) - { - if (value.IsNull()) - { - DataModelLogger::LogString(label, indent, "null"); - } - else - { - DataModelLogger::LogValue(label, indent, value.Value()); - } - - return CHIP_NO_ERROR; - } - - template - static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::Optional & value) - { - if (value.HasValue()) - { - DataModelLogger::LogValue(label, indent, value.Value()); - } - - return CHIP_NO_ERROR; - } - -#include - - static void LogString(size_t indent, const std::string string) { LogString("", indent, string); } - - static void LogString(const std::string label, size_t indent, const std::string string) - { - std::string indentation; - for (size_t i = 0; i < indent; ++i) - { - indentation.append(" "); - } - - ChipLogProgress(chipTool, "%s%s%s %s", indentation.c_str(), label.c_str(), label.size() ? ":" : "", string.c_str()); - } -}; diff --git a/examples/tv-casting-app/tv-casting-common/commands/clusters/ModelCommand.cpp b/examples/tv-casting-app/tv-casting-common/commands/clusters/ModelCommand.cpp index c886c04cf7bce7..bacbcfe98d6464 100644 --- a/examples/tv-casting-app/tv-casting-common/commands/clusters/ModelCommand.cpp +++ b/examples/tv-casting-app/tv-casting-common/commands/clusters/ModelCommand.cpp @@ -16,7 +16,7 @@ * */ -#include "ModelCommand.h" +#include #include #include @@ -28,23 +28,23 @@ CHIP_ERROR ModelCommand::RunCommand() { FabricIndex fabricIndex = CastingServer::GetInstance()->CurrentFabricIndex(); - if (mNodeId == 0) + if (mDestinationId == 0) { ChipLogProgress(chipTool, "nodeId set to 0, using default for fabric %d", fabricIndex); - mNodeId = CastingServer::GetInstance()->GetVideoPlayerNodeForFabricIndex(fabricIndex); + mDestinationId = CastingServer::GetInstance()->GetVideoPlayerNodeForFabricIndex(fabricIndex); } else { // potentially change fabric index if this is not the right one for the given nodeId - fabricIndex = CastingServer::GetInstance()->GetVideoPlayerFabricIndexForNode(mNodeId); + fabricIndex = CastingServer::GetInstance()->GetVideoPlayerFabricIndexForNode(mDestinationId); } - ChipLogProgress(chipTool, "Sending command to node 0x%" PRIx64, mNodeId); + ChipLogProgress(chipTool, "Sending command to node 0x%" PRIx64, mDestinationId); - if (IsGroupId(mNodeId)) + if (IsGroupId(mDestinationId)) { - ChipLogProgress(chipTool, "Sending command to group 0x%x", GroupIdFromNodeId(mNodeId)); + ChipLogProgress(chipTool, "Sending command to group 0x%x", GroupIdFromNodeId(mDestinationId)); - return SendGroupCommand(GroupIdFromNodeId(mNodeId), fabricIndex); + return SendGroupCommand(GroupIdFromNodeId(mDestinationId), fabricIndex); } Server * server = &(chip::Server::GetInstance()); @@ -55,7 +55,7 @@ CHIP_ERROR ModelCommand::RunCommand() return CHIP_ERROR_INVALID_FABRIC_INDEX; } - PeerId peerID = fabric->GetPeerIdForNode(mNodeId); + PeerId peerID = fabric->GetPeerIdForNode(mDestinationId); server->GetCASESessionManager()->FindOrEstablishSession(peerID, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); return CHIP_NO_ERROR; diff --git a/examples/tv-casting-app/tv-casting-common/commands/clusters/ModelCommand.h b/examples/tv-casting-app/tv-casting-common/commands/clusters/ModelCommand.h deleted file mode 100644 index daab38b420bbdf..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/clusters/ModelCommand.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2020 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -#include "../common/CHIPCommand.h" -#include - -class ModelCommand : public CHIPCommand -{ -public: - ModelCommand(const char * commandName, CredentialIssuerCommands * credsIssuerConfig) : - CHIPCommand(commandName, credsIssuerConfig), mOnDeviceConnectedCallback(OnDeviceConnectedFn, this), - mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this) - {} - - void AddArguments() - { - AddArgument("node-id/group-id", 0, UINT64_MAX, &mNodeId); - AddArgument("endpoint-id-ignored-for-group-commands", 0, UINT16_MAX, &mEndPointId); - AddArgument("timeout", 0, UINT16_MAX, &mTimeout); - } - - /////////// CHIPCommand Interface ///////// - CHIP_ERROR RunCommand() override; - chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(mTimeout.ValueOr(10)); } - - virtual CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endPointIds) = 0; - - virtual CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) { return CHIP_ERROR_BAD_REQUEST; }; - - void Shutdown() override; - -protected: - chip::Optional mTimeout; - -private: - chip::NodeId mNodeId; - std::vector mEndPointId; - - static void OnDeviceConnectedFn(void * context, chip::OperationalDeviceProxy * device); - static void OnDeviceConnectionFailureFn(void * context, PeerId peerId, CHIP_ERROR error); - - chip::Callback::Callback mOnDeviceConnectedCallback; - chip::Callback::Callback mOnDeviceConnectionFailureCallback; -}; diff --git a/examples/tv-casting-app/tv-casting-common/commands/clusters/ReportCommand.h b/examples/tv-casting-app/tv-casting-common/commands/clusters/ReportCommand.h deleted file mode 100644 index f99c5528892162..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/clusters/ReportCommand.h +++ /dev/null @@ -1,576 +0,0 @@ -/* - * Copyright (c) 2020 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -#include - -#include "DataModelLogger.h" -#include "ModelCommand.h" - -constexpr uint8_t kMaxAllowedPaths = 10; - -class ReportCommand : public ModelCommand, public chip::app::ReadClient::Callback -{ -public: - ReportCommand(const char * commandName, CredentialIssuerCommands * credsIssuerConfig) : - ModelCommand(commandName, credsIssuerConfig), mBufferedReadAdapter(*this) - {} - - virtual void OnAttributeSubscription(){}; - virtual void OnEventSubscription(){}; - - /////////// ReadClient Callback Interface ///////// - void OnAttributeData(const chip::app::ConcreteDataAttributePath & path, chip::TLV::TLVReader * data, - const chip::app::StatusIB & status) override - { - CHIP_ERROR error = status.ToChipError(); - if (CHIP_NO_ERROR != error) - { - ChipLogError(chipTool, "Response Failure: %s", chip::ErrorStr(error)); - mError = error; - return; - } - - if (data == nullptr) - { - ChipLogError(chipTool, "Response Failure: No Data"); - mError = CHIP_ERROR_INTERNAL; - return; - } - - error = DataModelLogger::LogAttribute(path, data); - if (CHIP_NO_ERROR != error) - { - ChipLogError(chipTool, "Response Failure: Can not decode Data"); - mError = error; - return; - } - } - - void OnEventData(const chip::app::EventHeader & eventHeader, chip::TLV::TLVReader * data, - const chip::app::StatusIB * status) override - { - if (status != nullptr) - { - CHIP_ERROR error = status->ToChipError(); - if (CHIP_NO_ERROR != error) - { - ChipLogError(chipTool, "Response Failure: %s", chip::ErrorStr(error)); - mError = error; - return; - } - } - - if (data == nullptr) - { - ChipLogError(chipTool, "Response Failure: No Data"); - mError = CHIP_ERROR_INTERNAL; - return; - } - - CHIP_ERROR error = DataModelLogger::LogEvent(eventHeader, data); - if (CHIP_NO_ERROR != error) - { - ChipLogError(chipTool, "Response Failure: Can not decode Data"); - mError = error; - return; - } - } - - void OnError(CHIP_ERROR error) override - { - ChipLogProgress(chipTool, "Error: %s", chip::ErrorStr(error)); - mError = error; - } - - void OnDone(chip::app::ReadClient *) override - { - mReadClient.reset(); - SetCommandExitStatus(mError); - } - - void OnSubscriptionEstablished(chip::SubscriptionId subscriptionId) override { OnAttributeSubscription(); } - -protected: - CHIP_ERROR ReportAttribute(chip::DeviceProxy * 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> & dataVersions = chip::NullOptional) - { - 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); - 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) - { - pathsCount = clusterCount; - } - else if (multipleClusters) - { - pathsCount = clusterCount; - } - else if (multipleAttributes) - { - pathsCount = attributeCount; - } - else if (multipleEndpoints) - { - pathsCount = endpointCount; - } - else if (multipleDataVersions) - { - pathsCount = dataVersionsCount; - } - else - { - ChipLogError( - chipTool, - "\n%sAttribute commands targeting multiple paths needs to have: \n \t * One element with multiple ids (for " - "example 1 cluster id, 1 attribute id, 2 endpoint ids)\n\t * Or the same " - "number of ids (for examples 2 cluster ids, 2 attribute ids and 2 endpoint ids).\n The current command has %u " - "cluster ids, %u attribute ids, %u endpoint ids.", - interactionType == chip::app::ReadClient::InteractionType::Subscribe ? "Subscribe" : "Read", - static_cast(clusterCount), static_cast(attributeCount), - static_cast(endpointCount)); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - 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); - chip::AttributeId attributeId = attributeIds.at((hasSameIdsCount || multipleAttributes) ? i : 0); - chip::EndpointId endpointId = endpointIds.at((hasSameIdsCount || multipleEndpoints) ? i : 0); - - ChipLogProgress(chipTool, "\tcluster " ChipLogFormatMEI ", attribute: " ChipLogFormatMEI ", endpoint %u", - ChipLogValueMEI(clusterId), ChipLogValueMEI(attributeId), endpointId); - attributePathParams[i].mClusterId = clusterId; - attributePathParams[i].mAttributeId = attributeId; - attributePathParams[i].mEndpointId = endpointId; - - 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(dataVersion); - } - } - - chip::app::ReadPrepareParams params(device->GetSecureSession().Value()); - params.mpEventPathParamsList = nullptr; - params.mEventPathParamsListSize = 0; - params.mpAttributePathParamsList = attributePathParams; - params.mAttributePathParamsListSize = pathsCount; - - if (mFabricFiltered.HasValue()) - { - params.mIsFabricFiltered = mFabricFiltered.Value(); - } - - if (dataVersions.HasValue()) - { - params.mpDataVersionFilterList = dataVersionFilter; - params.mDataVersionFilterListSize = pathsCount; - } - - if (interactionType == chip::app::ReadClient::InteractionType::Subscribe) - { - params.mMinIntervalFloorSeconds = minInterval; - params.mMaxIntervalCeilingSeconds = maxInterval; - if (mKeepSubscriptions.HasValue()) - { - params.mKeepSubscriptions = mKeepSubscriptions.Value(); - } - } - - mReadClient = std::make_unique(chip::app::InteractionModelEngine::GetInstance(), - device->GetExchangeManager(), mBufferedReadAdapter, interactionType); - return mReadClient->SendRequest(params); - } - - CHIP_ERROR ReportEvent(chip::DeviceProxy * device, std::vector endpointIds, - std::vector clusterIds, std::vector eventIds, - chip::app::ReadClient::InteractionType interactionType, uint16_t minInterval = 0, - uint16_t maxInterval = 0) - { - const size_t clusterCount = clusterIds.size(); - const size_t eventCount = eventIds.size(); - const size_t endpointCount = endpointIds.size(); - - 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); - - const bool hasSameIdsCount = (clusterCount == eventCount) && (clusterCount == endpointCount); - const bool multipleClusters = clusterCount > 1 && eventCount == 1 && endpointCount == 1; - const bool multipleEvents = eventCount > 1 && clusterCount == 1 && endpointCount == 1; - const bool multipleEndpoints = endpointCount > 1 && clusterCount == 1 && eventCount == 1; - - size_t pathsCount = 0; - if (hasSameIdsCount) - { - pathsCount = clusterCount; - } - else if (multipleClusters) - { - pathsCount = clusterCount; - } - else if (multipleEvents) - { - pathsCount = eventCount; - } - else if (multipleEndpoints) - { - pathsCount = endpointCount; - } - else - { - ChipLogError(chipTool, - "\n%sEvent command targeting multiple paths needs to have: \n \t * One element with multiple ids (for " - "example 1 cluster id, 1 event id, 2 endpoint ids)\n\t * Or the same " - "number of ids (for examples 2 cluster ids, 2 event ids and 2 endpoint ids).\n The current command has %u " - "cluster ids, %u event ids, %u endpoint ids.", - interactionType == chip::app::ReadClient::InteractionType::Subscribe ? "Subscribe" : "Read", - static_cast(clusterCount), static_cast(eventCount), - static_cast(endpointCount)); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - chip::app::EventPathParams eventPathParams[kMaxAllowedPaths]; - - ChipLogProgress(chipTool, "Sending %sEvent to:", - interactionType == chip::app::ReadClient::InteractionType::Subscribe ? "Subscribe" : "Read"); - for (size_t i = 0; i < pathsCount; i++) - { - chip::ClusterId clusterId = clusterIds.at((hasSameIdsCount || multipleClusters) ? i : 0); - chip::EventId eventId = eventIds.at((hasSameIdsCount || multipleEvents) ? i : 0); - chip::EndpointId endpointId = endpointIds.at((hasSameIdsCount || multipleEndpoints) ? i : 0); - - ChipLogProgress(chipTool, "\tcluster " ChipLogFormatMEI ", event: " ChipLogFormatMEI ", endpoint %u", - ChipLogValueMEI(clusterId), ChipLogValueMEI(eventId), endpointId); - eventPathParams[i].mClusterId = clusterId; - eventPathParams[i].mEventId = eventId; - eventPathParams[i].mEndpointId = endpointId; - } - - chip::app::ReadPrepareParams params(device->GetSecureSession().Value()); - params.mpEventPathParamsList = eventPathParams; - params.mEventPathParamsListSize = pathsCount; - params.mEventNumber = mEventNumber; - params.mpAttributePathParamsList = nullptr; - params.mAttributePathParamsListSize = 0; - - if (interactionType == chip::app::ReadClient::InteractionType::Subscribe) - { - params.mMinIntervalFloorSeconds = minInterval; - params.mMaxIntervalCeilingSeconds = maxInterval; - if (mKeepSubscriptions.HasValue()) - { - params.mKeepSubscriptions = mKeepSubscriptions.Value(); - } - } - - mReadClient = std::make_unique(chip::app::InteractionModelEngine::GetInstance(), - device->GetExchangeManager(), mBufferedReadAdapter, interactionType); - return mReadClient->SendRequest(params); - } - - // Use a 3x-longer-than-default timeout because wildcard reads can take a - // while. - chip::System::Clock::Timeout GetWaitDuration() const override - { - return mTimeout.HasValue() ? chip::System::Clock::Seconds16(mTimeout.Value()) : (ModelCommand::GetWaitDuration() * 3); - } - - std::unique_ptr mReadClient; - chip::app::BufferedReadCallback mBufferedReadAdapter; - - // mFabricFiltered is really only used by the attribute commands, but we end - // up needing it in our class's shared code. - chip::Optional mFabricFiltered; - - // mKeepSubscriptions is really only used by the subscribe commands, but we end - // up needing it in our class's shared code. - chip::Optional mKeepSubscriptions; - chip::Optional mEventNumber; - - CHIP_ERROR mError = CHIP_NO_ERROR; -}; - -class ReadAttribute : public ReportCommand -{ -public: - ReadAttribute(CredentialIssuerCommands * credsIssuerConfig) : ReportCommand("read-by-id", credsIssuerConfig) - { - AddArgument("cluster-id", 0, UINT32_MAX, &mClusterIds); - AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeIds); - AddArgument("data-version", 0, UINT32_MAX, &mDataVersion); - AddArgument("fabric-filtered", 0, 1, &mFabricFiltered); - ReportCommand::AddArguments(); - } - - ReadAttribute(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) : - ReportCommand("read-by-id", credsIssuerConfig), mClusterIds(1, clusterId) - { - AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeIds); - AddArgument("data-version", 0, UINT32_MAX, &mDataVersion); - AddArgument("fabric-filtered", 0, 1, &mFabricFiltered); - ReportCommand::AddArguments(); - } - - ReadAttribute(chip::ClusterId clusterId, const char * attributeName, chip::AttributeId attributeId, - CredentialIssuerCommands * credsIssuerConfig) : - ReportCommand("read", credsIssuerConfig), - mClusterIds(1, clusterId), mAttributeIds(1, attributeId) - { - AddArgument("attr-name", attributeName); - AddArgument("data-version", 0, UINT32_MAX, &mDataVersion); - AddArgument("fabric-filtered", 0, 1, &mFabricFiltered); - ReportCommand::AddArguments(); - } - - ~ReadAttribute() {} - - CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override - { - return ReportCommand::ReportAttribute(device, endpointIds, mClusterIds, mAttributeIds, - chip::app::ReadClient::InteractionType::Read, 0, 0, mDataVersion); - } - -private: - std::vector mClusterIds; - std::vector mAttributeIds; - chip::Optional> mDataVersion; -}; - -class SubscribeAttribute : public ReportCommand -{ -public: - SubscribeAttribute(CredentialIssuerCommands * credsIssuerConfig) : ReportCommand("subscribe-by-id", credsIssuerConfig) - { - AddArgument("cluster-id", 0, UINT32_MAX, &mClusterIds); - AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeIds); - AddArgument("min-interval", 0, UINT16_MAX, &mMinInterval); - AddArgument("max-interval", 0, UINT16_MAX, &mMaxInterval); - AddArgument("data-version", 0, UINT32_MAX, &mDataVersion); - AddArgument("fabric-filtered", 0, 1, &mFabricFiltered); - AddArgument("keepSubscriptions", 0, 1, &mKeepSubscriptions); - ReportCommand::AddArguments(); - } - - SubscribeAttribute(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) : - ReportCommand("subscribe-by-id", credsIssuerConfig), mClusterIds(1, clusterId) - { - AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeIds); - AddArgument("min-interval", 0, UINT16_MAX, &mMinInterval); - AddArgument("max-interval", 0, UINT16_MAX, &mMaxInterval); - AddArgument("data-version", 0, UINT32_MAX, &mDataVersion); - AddArgument("fabric-filtered", 0, 1, &mFabricFiltered); - AddArgument("keepSubscriptions", 0, 1, &mKeepSubscriptions); - ReportCommand::AddArguments(); - } - - SubscribeAttribute(chip::ClusterId clusterId, const char * attributeName, chip::AttributeId attributeId, - CredentialIssuerCommands * credsIssuerConfig) : - ReportCommand("subscribe", credsIssuerConfig), - mClusterIds(1, clusterId), mAttributeIds(1, attributeId) - { - AddArgument("attr-name", attributeName); - AddArgument("min-interval", 0, UINT16_MAX, &mMinInterval); - AddArgument("max-interval", 0, UINT16_MAX, &mMaxInterval); - AddArgument("data-version", 0, UINT32_MAX, &mDataVersion); - AddArgument("fabric-filtered", 0, 1, &mFabricFiltered); - AddArgument("keepSubscriptions", 0, 1, &mKeepSubscriptions); - ReportCommand::AddArguments(); - } - - ~SubscribeAttribute() {} - - CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override - { - return ReportCommand::ReportAttribute(device, endpointIds, mClusterIds, mAttributeIds, - chip::app::ReadClient::InteractionType::Subscribe, mMinInterval, mMaxInterval, - mDataVersion); - } - - chip::System::Clock::Timeout GetWaitDuration() const override { return ReportCommand::GetWaitDuration(); } - - void OnAttributeSubscription() override - { - // The ReadClient instance can not be released directly into the OnAttributeSubscription - // callback since it happens to be called by ReadClient itself which is doing additional - // work after that. - chip::DeviceLayer::PlatformMgr().ScheduleWork( - [](intptr_t arg) { - auto * command = reinterpret_cast(arg); - if (!command->IsInteractive()) - { - command->mReadClient.reset(); - } - command->SetCommandExitStatus(CHIP_NO_ERROR); - }, - reinterpret_cast(this)); - } - -private: - std::vector mClusterIds; - std::vector mAttributeIds; - - uint16_t mMinInterval; - uint16_t mMaxInterval; - chip::Optional> mDataVersion; -}; - -class ReadEvent : public ReportCommand -{ -public: - ReadEvent(CredentialIssuerCommands * credsIssuerConfig) : ReportCommand("read-event-by-id", credsIssuerConfig) - { - AddArgument("cluster-id", 0, UINT32_MAX, &mClusterIds); - AddArgument("event-id", 0, UINT32_MAX, &mEventIds); - AddArgument("event-min", 0, UINT64_MAX, &mEventNumber); - ReportCommand::AddArguments(); - } - - ReadEvent(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) : - ReportCommand("read-event-by-id", credsIssuerConfig), mClusterIds(1, clusterId) - { - AddArgument("event-id", 0, UINT32_MAX, &mEventIds); - AddArgument("event-min", 0, UINT64_MAX, &mEventNumber); - ReportCommand::AddArguments(); - } - - ReadEvent(chip::ClusterId clusterId, const char * eventName, chip::EventId eventId, - CredentialIssuerCommands * credsIssuerConfig) : - ReportCommand("read-event", credsIssuerConfig), - mClusterIds(1, clusterId), mEventIds(1, eventId) - { - AddArgument("event-name", eventName); - AddArgument("event-min", 0, UINT64_MAX, &mEventNumber); - ReportCommand::AddArguments(); - } - - ~ReadEvent() {} - - CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override - { - return ReportCommand::ReportEvent(device, endpointIds, mClusterIds, mEventIds, - chip::app::ReadClient::InteractionType::Read); - } - -private: - std::vector mClusterIds; - std::vector mEventIds; -}; - -class SubscribeEvent : public ReportCommand -{ -public: - SubscribeEvent(CredentialIssuerCommands * credsIssuerConfig) : ReportCommand("subscribe-event-by-id", credsIssuerConfig) - { - 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("keepSubscriptions", 0, 1, &mKeepSubscriptions); - AddArgument("event-min", 0, UINT64_MAX, &mEventNumber); - ReportCommand::AddArguments(); - } - - SubscribeEvent(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) : - ReportCommand("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("keepSubscriptions", 0, 1, &mKeepSubscriptions); - AddArgument("event-min", 0, UINT64_MAX, &mEventNumber); - ReportCommand::AddArguments(); - } - - SubscribeEvent(chip::ClusterId clusterId, const char * eventName, chip::EventId eventId, - CredentialIssuerCommands * credsIssuerConfig) : - ReportCommand("subscribe-event", credsIssuerConfig), - mClusterIds(1, clusterId), mEventIds(1, eventId) - { - AddArgument("attr-name", eventName); - AddArgument("min-interval", 0, UINT16_MAX, &mMinInterval); - AddArgument("max-interval", 0, UINT16_MAX, &mMaxInterval); - AddArgument("keepSubscriptions", 0, 1, &mKeepSubscriptions); - AddArgument("event-min", 0, UINT64_MAX, &mEventNumber); - ReportCommand::AddArguments(); - } - - ~SubscribeEvent() {} - - CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override - { - return ReportCommand::ReportEvent(device, endpointIds, mClusterIds, mEventIds, - chip::app::ReadClient::InteractionType::Subscribe, mMinInterval, mMaxInterval); - } - - chip::System::Clock::Timeout GetWaitDuration() const override { return ReportCommand::GetWaitDuration(); } - - void OnEventSubscription() override - { - // The ReadClient instance can not be released directly into the OnEventSubscription - // callback since it happens to be called by ReadClient itself which is doing additional - // work after that. - chip::DeviceLayer::PlatformMgr().ScheduleWork( - [](intptr_t arg) { - auto * command = reinterpret_cast(arg); - if (!command->IsInteractive()) - { - command->mReadClient.reset(); - } - command->SetCommandExitStatus(CHIP_NO_ERROR); - }, - reinterpret_cast(this)); - } - -private: - std::vector mClusterIds; - std::vector mEventIds; - - uint16_t mMinInterval; - uint16_t mMaxInterval; -}; diff --git a/examples/tv-casting-app/tv-casting-common/commands/clusters/SubscriptionsCommands.h b/examples/tv-casting-app/tv-casting-common/commands/clusters/SubscriptionsCommands.h deleted file mode 100644 index b1bada5c17a280..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/clusters/SubscriptionsCommands.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -#include "../common/CHIPCommand.h" -#include "../common/Commands.h" - -class ShutdownSubscription : public CHIPCommand -{ -public: - ShutdownSubscription(CredentialIssuerCommands * credsIssuerConfig) : CHIPCommand("shutdown-subscription", credsIssuerConfig) - { - AddArgument("subscription-id", 0, UINT64_MAX, &mSubscriptionId); - } - - /////////// CHIPCommand Interface ///////// - CHIP_ERROR RunCommand() override - { - CHIP_ERROR err = chip::app::InteractionModelEngine::GetInstance()->ShutdownSubscription(mSubscriptionId); - SetCommandExitStatus(err); - return CHIP_NO_ERROR; - } - chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(10); } - -private: - chip::SubscriptionId mSubscriptionId; -}; - -class ShutdownSubscriptions : public CHIPCommand -{ -public: - ShutdownSubscriptions(CredentialIssuerCommands * credsIssuerConfig) : CHIPCommand("shutdown-subscriptions", credsIssuerConfig) - { - AddArgument("fabric-index", 0, UINT64_MAX, &mFabricIndex); - AddArgument("node-id", 0, UINT64_MAX, &mNodeId); - } - - /////////// CHIPCommand Interface ///////// - CHIP_ERROR RunCommand() override - { - CHIP_ERROR err = chip::app::InteractionModelEngine::GetInstance()->ShutdownSubscriptions(mFabricIndex, mNodeId); - SetCommandExitStatus(err); - return CHIP_NO_ERROR; - } - chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(10); } - -private: - chip::FabricIndex mFabricIndex; - chip::NodeId mNodeId; -}; - -void registerClusterSubscriptions(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) -{ - const char * clusterName = "Subscriptions"; - - commands_list clusterCommands = { - make_unique(credsIssuerConfig), // - make_unique(credsIssuerConfig), // - }; - - commands.Register(clusterName, clusterCommands); -} diff --git a/examples/tv-casting-app/tv-casting-common/commands/clusters/WriteAttributeCommand.h b/examples/tv-casting-app/tv-casting-common/commands/clusters/WriteAttributeCommand.h deleted file mode 100644 index dea6b9c5e159ee..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/clusters/WriteAttributeCommand.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2022 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -#include - -#include "DataModelLogger.h" -#include "ModelCommand.h" - -class WriteAttribute : public ModelCommand, public chip::app::WriteClient::Callback -{ -public: - WriteAttribute(CredentialIssuerCommands * credsIssuerConfig) : ModelCommand("write-by-id", credsIssuerConfig) - { - AddArgument("cluster-id", 0, UINT32_MAX, &mClusterId); - AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeId); - AddArgument("attribute-value", &mAttributeValue); - AddArgument("timedInteractionTimeoutMs", 0, UINT16_MAX, &mTimedInteractionTimeoutMs); - AddArgument("data-version", 0, UINT32_MAX, &mDataVersion); - AddArgument("suppressResponse", 0, 1, &mSuppressResponse); - ModelCommand::AddArguments(); - } - - WriteAttribute(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) : - ModelCommand("write-by-id", credsIssuerConfig), mClusterId(clusterId) - { - AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeId); - AddArgument("attribute-value", &mAttributeValue); - AddArgument("timedInteractionTimeoutMs", 0, UINT16_MAX, &mTimedInteractionTimeoutMs); - AddArgument("data-version", 0, UINT32_MAX, &mDataVersion); - AddArgument("suppressResponse", 0, 1, &mSuppressResponse); - ModelCommand::AddArguments(); - } - - WriteAttribute(const char * attributeName, CredentialIssuerCommands * credsIssuerConfig) : - ModelCommand("write", credsIssuerConfig) - { - AddArgument("timedInteractionTimeoutMs", 0, UINT16_MAX, &mTimedInteractionTimeoutMs); - AddArgument("data-version", 0, UINT32_MAX, &mDataVersion); - AddArgument("suppressResponse", 0, 1, &mSuppressResponse); - } - - ~WriteAttribute() {} - - CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override - { - return WriteAttribute::SendCommand(device, endpointIds.at(0), mClusterId, mAttributeId, mAttributeValue); - } - - CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override - { - return WriteAttribute::SendGroupCommand(groupId, fabricIndex, mClusterId, mAttributeId, mAttributeValue); - } - - /////////// WriteClient Callback Interface ///////// - void OnResponse(const chip::app::WriteClient * client, const chip::app::ConcreteDataAttributePath & path, - chip::app::StatusIB status) override - { - CHIP_ERROR error = status.ToChipError(); - if (CHIP_NO_ERROR != error) - { - ChipLogError(chipTool, "Response Failure: %s", chip::ErrorStr(error)); - mError = error; - } - } - - void OnError(const chip::app::WriteClient * client, CHIP_ERROR error) override - { - ChipLogProgress(chipTool, "Error: %s", chip::ErrorStr(error)); - mError = error; - } - - void OnDone(chip::app::WriteClient * client) override - { - mWriteClient.reset(); - SetCommandExitStatus(mError); - } - - template - CHIP_ERROR SendCommand(chip::DeviceProxy * device, chip::EndpointId endpointId, chip::ClusterId clusterId, - chip::AttributeId attributeId, const T & value) - { - ChipLogProgress(chipTool, "Sending WriteAttribute to cluster " ChipLogFormatMEI " on endpoint %u", - ChipLogValueMEI(clusterId), endpointId); - chip::app::AttributePathParams attributePathParams; - if (!device->GetSecureSession().Value()->IsGroupSession()) - { - attributePathParams.mEndpointId = endpointId; - } - attributePathParams.mClusterId = clusterId; - attributePathParams.mAttributeId = attributeId; - - mWriteClient = std::make_unique(device->GetExchangeManager(), this, mTimedInteractionTimeoutMs, - mSuppressResponse.ValueOr(false)); - - ReturnErrorOnFailure(mWriteClient->EncodeAttribute(attributePathParams, value, mDataVersion)); - - return mWriteClient->SendWriteRequest(device->GetSecureSession().Value()); - } - - template - CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex, chip::ClusterId clusterId, - chip::AttributeId attributeId, const T & value) - { - - chip::app::AttributePathParams attributePathParams; - attributePathParams.mClusterId = clusterId; - attributePathParams.mAttributeId = attributeId; - - chip::Messaging::ExchangeManager * exchangeManager = chip::app::InteractionModelEngine::GetInstance()->GetExchangeManager(); - - ChipLogDetail(chipTool, "Sending Write Attribute to Group %u, on Fabric %x, for cluster %u with attributeId %u", groupId, - fabricIndex, clusterId, attributeId); - - auto writeClient = chip::Platform::MakeUnique(exchangeManager, this, mTimedInteractionTimeoutMs); - VerifyOrReturnError(writeClient != nullptr, CHIP_ERROR_NO_MEMORY); - ReturnErrorOnFailure(writeClient->EncodeAttribute(attributePathParams, value, mDataVersion)); - - chip::Transport::OutgoingGroupSession session(groupId, fabricIndex); - ReturnErrorOnFailure(writeClient->SendWriteRequest(chip::SessionHandle(session))); - writeClient.release(); - - return CHIP_NO_ERROR; - } - -private: - chip::ClusterId mClusterId; - chip::AttributeId mAttributeId; - CHIP_ERROR mError = CHIP_NO_ERROR; - chip::Optional mTimedInteractionTimeoutMs; - chip::Optional mDataVersion = chip::NullOptional; - chip::Optional mSuppressResponse; - CustomArgument mAttributeValue; - std::unique_ptr mWriteClient; -}; diff --git a/examples/tv-casting-app/tv-casting-common/commands/common/CHIPCommand.cpp b/examples/tv-casting-app/tv-casting-common/commands/common/CHIPCommand.cpp index a6034cb1969686..3a3995484e6e75 100644 --- a/examples/tv-casting-app/tv-casting-common/commands/common/CHIPCommand.cpp +++ b/examples/tv-casting-app/tv-casting-common/commands/common/CHIPCommand.cpp @@ -16,7 +16,7 @@ * */ -#include "CHIPCommand.h" +#include #include #include diff --git a/examples/tv-casting-app/tv-casting-common/commands/common/CHIPCommand.h b/examples/tv-casting-app/tv-casting-common/commands/common/CHIPCommand.h deleted file mode 100644 index 7d8f6d09f30371..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/common/CHIPCommand.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2021 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -#include "Command.h" -#include -#include -#include - -#pragma once - -class PersistentStorage; - -constexpr const char kIdentityAlpha[] = "alpha"; -constexpr const char kIdentityBeta[] = "beta"; -constexpr const char kIdentityGamma[] = "gamma"; -// The null fabric commissioner is a commissioner that isn't on a fabric. -// This is a legal configuration in which the commissioner delegates -// operational communication and invocation of the commssioning complete -// command to a separate on-fabric administrator node. -// -// The null-fabric-commissioner identity is provided here to demonstrate the -// commissioner portion of such an architecture. The null-fabric-commissioner -// can carry a commissioning flow up until the point of operational channel -// (CASE) communcation. -constexpr const char kIdentityNull[] = "null-fabric-commissioner"; - -class CHIPCommand : public Command -{ -public: - using ChipDeviceCommissioner = ::chip::Controller::DeviceCommissioner; - using ChipDeviceController = ::chip::Controller::DeviceController; - using IPAddress = ::chip::Inet::IPAddress; - using NodeId = ::chip::NodeId; - using PeerId = ::chip::PeerId; - using PeerAddress = ::chip::Transport::PeerAddress; - - static constexpr uint16_t kMaxGroupsPerFabric = 5; - static constexpr uint16_t kMaxGroupKeysPerFabric = 8; - - CHIPCommand(const char * commandName, CredentialIssuerCommands * credIssuerCmds) : - Command(commandName) // , mCredIssuerCmds(credIssuerCmds) - { -#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED - AddArgument("trace_file", &mTraceFile); - AddArgument("trace_log", 0, 1, &mTraceLog); -#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED - } - - /////////// Command Interface ///////// - CHIP_ERROR Run() override; - - void SetCommandExitStatus(CHIP_ERROR status) - { - mCommandExitStatus = status; - StopWaiting(); - } - -protected: - // Will be called in a setting in which it's safe to touch the CHIP - // stack. The rules for Run() are as follows: - // - // 1) If error is returned, Run() must not call SetCommandExitStatus. - // 2) If success is returned Run() must either have called - // SetCommandExitStatus() or scheduled async work that will do that. - virtual CHIP_ERROR RunCommand() = 0; - - // Get the wait duration, in seconds, before the command times out. - virtual chip::System::Clock::Timeout GetWaitDuration() const = 0; - - // Shut down the command, in case any work needs to be done after the event - // loop has been stopped. - virtual void Shutdown() {} - -private: - static void RunQueuedCommand(intptr_t commandArg); - - CHIP_ERROR mCommandExitStatus = CHIP_ERROR_INTERNAL; - - CHIP_ERROR StartWaiting(chip::System::Clock::Timeout seconds); - void StopWaiting(); - - void StartTracing(); - void StopTracing(); - -#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED - chip::Optional mTraceFile; - chip::Optional mTraceLog; -#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED -}; diff --git a/examples/tv-casting-app/tv-casting-common/commands/common/Command.cpp b/examples/tv-casting-app/tv-casting-common/commands/common/Command.cpp deleted file mode 100644 index b67880b2f2f38e..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/common/Command.cpp +++ /dev/null @@ -1,747 +0,0 @@ -/* - * Copyright (c) 2020 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#include "Command.h" -#include "platform/PlatformManager.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -constexpr const char * kOptionalArgumentPrefix = "--"; -constexpr size_t kOptionalArgumentPrefixLength = 2; - -bool Command::InitArguments(int argc, char ** argv) -{ - bool isValidCommand = false; - - size_t argvExtraArgsCount = (size_t) argc; - size_t mandatoryArgsCount = 0; - size_t optionalArgsCount = 0; - for (size_t i = 0; i < mArgs.size(); i++) - { - if (mArgs[i].isOptional()) - { - optionalArgsCount++; - } - else - { - mandatoryArgsCount++; - argvExtraArgsCount--; - } - } - - VerifyOrExit((size_t)(argc) >= mandatoryArgsCount && (argvExtraArgsCount == 0 || (argvExtraArgsCount && optionalArgsCount)), - ChipLogError(chipTool, "InitArgs: Wrong arguments number: %d instead of %u", argc, - static_cast(mandatoryArgsCount))); - - // Initialize mandatory arguments - for (size_t i = 0; i < mandatoryArgsCount; i++) - { - char * arg = argv[i]; - if (!InitArgument(i, arg)) - { - ExitNow(); - } - } - - // Initialize optional arguments - // Optional arguments expect a name and a value, so i is increased by 2 on every step. - for (size_t i = mandatoryArgsCount; i < (size_t) argc; i += 2) - { - bool found = false; - for (size_t j = mandatoryArgsCount; j < mandatoryArgsCount + optionalArgsCount; j++) - { - // optional arguments starts with kOptionalArgumentPrefix - if (strlen(argv[i]) <= kOptionalArgumentPrefixLength && - strncmp(argv[i], kOptionalArgumentPrefix, kOptionalArgumentPrefixLength) != 0) - { - continue; - } - - if (strcmp(argv[i] + strlen(kOptionalArgumentPrefix), mArgs[j].name) == 0) - { - found = true; - - VerifyOrExit((size_t) argc > (i + 1), - ChipLogError(chipTool, "InitArgs: Optional argument %s missing value.", argv[i])); - if (!InitArgument(j, argv[i + 1])) - { - ExitNow(); - } - } - } - VerifyOrExit(found, ChipLogError(chipTool, "InitArgs: Optional argument %s does not exist.", argv[i])); - } - - isValidCommand = true; - -exit: - return isValidCommand; -} - -static bool ParseAddressWithInterface(const char * addressString, Command::AddressWithInterface * address) -{ - struct addrinfo hints; - struct addrinfo * result; - int ret; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; - ret = getaddrinfo(addressString, nullptr, &hints, &result); - if (ret < 0) - { - ChipLogError(chipTool, "Invalid address: %s", addressString); - return false; - } - - if (result->ai_family == AF_INET6) - { - struct sockaddr_in6 * addr = reinterpret_cast(result->ai_addr); - address->address = ::chip::Inet::IPAddress::FromSockAddr(*addr); - address->interfaceId = ::chip::Inet::InterfaceId(addr->sin6_scope_id); - } -#if INET_CONFIG_ENABLE_IPV4 - else if (result->ai_family == AF_INET) - { - address->address = ::chip::Inet::IPAddress::FromSockAddr(*reinterpret_cast(result->ai_addr)); - address->interfaceId = chip::Inet::InterfaceId::Null(); - } -#endif // INET_CONFIG_ENABLE_IPV4 - else - { - ChipLogError(chipTool, "Unsupported address: %s", addressString); - return false; - } - - return true; -} - -// The callback should return whether the argument is valid, for the non-null -// case. It can't directly write to isValidArgument (by closing over it) -// because in the nullable-and-null case we need to do that from this function, -// via the return value. -template -bool HandleNullableOptional(Argument & arg, char * argValue, std::function callback) -{ - if (arg.isOptional()) - { - if (arg.isNullable()) - { - arg.value = &(reinterpret_cast> *>(arg.value)->Emplace()); - } - else - { - arg.value = &(reinterpret_cast *>(arg.value)->Emplace()); - } - } - - if (arg.isNullable()) - { - auto * nullable = reinterpret_cast *>(arg.value); - if (strcmp(argValue, "null") == 0) - { - nullable->SetNull(); - return true; - } - - arg.value = &(nullable->SetNonNull()); - } - - return callback(reinterpret_cast(arg.value)); -} - -bool Command::InitArgument(size_t argIndex, char * argValue) -{ - bool isValidArgument = false; - bool isHexNotation = strncmp(argValue, "0x", 2) == 0 || strncmp(argValue, "0X", 2) == 0; - - Argument arg = mArgs.at(argIndex); - switch (arg.type) - { - case ArgumentType::Complex: { - auto complexArgument = static_cast(arg.value); - return CHIP_NO_ERROR == complexArgument->Parse(arg.name, argValue); - } - - case ArgumentType::Custom: { - auto customArgument = static_cast(arg.value); - return CHIP_NO_ERROR == customArgument->Parse(arg.name, argValue); - } - - case ArgumentType::Vector16: - case ArgumentType::Vector32: { - std::vector values; - uint64_t min = chip::CanCastTo(arg.min) ? static_cast(arg.min) : 0; - uint64_t max = arg.max; - - std::stringstream ss(argValue); - while (ss.good()) - { - std::string valueAsString; - getline(ss, valueAsString, ','); - isHexNotation = strncmp(valueAsString.c_str(), "0x", 2) == 0 || strncmp(valueAsString.c_str(), "0X", 2) == 0; - - std::stringstream subss; - isHexNotation ? subss << std::hex << valueAsString : subss << valueAsString; - - uint64_t value; - subss >> value; - VerifyOrReturnError(!subss.fail() && subss.eof() && value >= min && value <= max, false); - values.push_back(value); - } - - if (arg.type == ArgumentType::Vector16) - { - auto vectorArgument = static_cast *>(arg.value); - for (uint64_t v : values) - { - vectorArgument->push_back(static_cast(v)); - } - } - else if (arg.type == ArgumentType::Vector32 && arg.flags != Argument::kOptional) - { - auto vectorArgument = static_cast *>(arg.value); - for (uint64_t v : values) - { - 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; - } - - case ArgumentType::Attribute: { - if (arg.isOptional() || arg.isNullable()) - { - isValidArgument = false; - } - else - { - char * value = reinterpret_cast(arg.value); - isValidArgument = (strcmp(argValue, value) == 0); - } - break; - } - - case ArgumentType::String: { - isValidArgument = HandleNullableOptional(arg, argValue, [&](auto * value) { - *value = argValue; - return true; - }); - break; - } - - case ArgumentType::CharString: { - isValidArgument = HandleNullableOptional(arg, argValue, [&](auto * value) { - *value = chip::Span(argValue, strlen(argValue)); - return true; - }); - break; - } - - case ArgumentType::OctetString: { - isValidArgument = HandleNullableOptional(arg, argValue, [&](auto * value) { - // We support two ways to pass an octet string argument. If it happens - // to be all-ASCII, you can just pass it in. Otherwise you can pass in - // 0x followed by the hex-encoded bytes. - size_t argLen = strlen(argValue); - static constexpr char hexPrefix[] = "hex:"; - constexpr size_t prefixLen = ArraySize(hexPrefix) - 1; // Don't count the null - if (strncmp(argValue, hexPrefix, prefixLen) == 0) - { - // Hex-encoded. Decode it into a temporary buffer first, so if we - // run into errors we can do correct "argument is not valid" logging - // that actually shows the value that was passed in. After we - // determine it's valid, modify the passed-in value to hold the - // right bytes, so we don't need to worry about allocating storage - // for this somewhere else. This works because the hex - // representation is always longer than the octet string it encodes, - // so we have enough space in argValue for the decoded version. - chip::Platform::ScopedMemoryBuffer buffer; - if (!buffer.Calloc(argLen)) // Bigger than needed, but it's fine. - { - return false; - } - - size_t octetCount = chip::Encoding::HexToBytes(argValue + prefixLen, argLen - prefixLen, buffer.Get(), argLen); - if (octetCount == 0) - { - return false; - } - - memcpy(argValue, buffer.Get(), octetCount); - *value = chip::ByteSpan(chip::Uint8::from_char(argValue), octetCount); - return true; - } - - // Just ASCII. Check for the "str:" prefix. - static constexpr char strPrefix[] = "str:"; - constexpr size_t strPrefixLen = ArraySize(strPrefix) - 1; // Don't count the null - if (strncmp(argValue, strPrefix, strPrefixLen) == 0) - { - // Skip the prefix - argValue += strPrefixLen; - argLen -= strPrefixLen; - } - *value = chip::ByteSpan(chip::Uint8::from_char(argValue), argLen); - return true; - }); - break; - } - - case ArgumentType::Bool: - case ArgumentType::Number_uint8: { - isValidArgument = HandleNullableOptional(arg, argValue, [&](auto * value) { - // stringstream treats uint8_t as char, which is not what we want here. - uint16_t tmpValue; - std::stringstream ss; - isHexNotation ? ss << std::hex << argValue : ss << argValue; - ss >> tmpValue; - if (chip::CanCastTo(tmpValue)) - { - *value = static_cast(tmpValue); - - uint64_t min = chip::CanCastTo(arg.min) ? static_cast(arg.min) : 0; - uint64_t max = arg.max; - return (!ss.fail() && ss.eof() && *value >= min && *value <= max); - } - - return false; - }); - break; - } - - case ArgumentType::Number_uint16: { - isValidArgument = HandleNullableOptional(arg, argValue, [&](auto * value) { - std::stringstream ss; - isHexNotation ? ss << std::hex << argValue : ss << argValue; - ss >> *value; - - uint64_t min = chip::CanCastTo(arg.min) ? static_cast(arg.min) : 0; - uint64_t max = arg.max; - return (!ss.fail() && ss.eof() && *value >= min && *value <= max); - }); - break; - } - - case ArgumentType::Number_uint32: { - isValidArgument = HandleNullableOptional(arg, argValue, [&](auto * value) { - std::stringstream ss; - isHexNotation ? ss << std::hex << argValue : ss << argValue; - ss >> *value; - - uint64_t min = chip::CanCastTo(arg.min) ? static_cast(arg.min) : 0; - uint64_t max = arg.max; - return (!ss.fail() && ss.eof() && *value >= min && *value <= max); - }); - break; - } - - case ArgumentType::Number_uint64: { - isValidArgument = HandleNullableOptional(arg, argValue, [&](auto * value) { - std::stringstream ss; - isHexNotation ? ss << std::hex << argValue : ss << argValue; - ss >> *value; - - uint64_t min = chip::CanCastTo(arg.min) ? static_cast(arg.min) : 0; - uint64_t max = arg.max; - return (!ss.fail() && ss.eof() && *value >= min && *value <= max); - }); - break; - } - - case ArgumentType::Number_int8: { - isValidArgument = HandleNullableOptional(arg, argValue, [&](auto * value) { - // stringstream treats int8_t as char, which is not what we want here. - int16_t tmpValue; - std::stringstream ss; - isHexNotation ? ss << std::hex << argValue : ss << argValue; - ss >> tmpValue; - if (chip::CanCastTo(tmpValue)) - { - *value = static_cast(tmpValue); - - int64_t min = arg.min; - int64_t max = chip::CanCastTo(arg.max) ? static_cast(arg.max) : INT64_MAX; - return (!ss.fail() && ss.eof() && *value >= min && *value <= max); - } - - return false; - }); - break; - } - - case ArgumentType::Number_int16: { - isValidArgument = HandleNullableOptional(arg, argValue, [&](auto * value) { - std::stringstream ss; - isHexNotation ? ss << std::hex << argValue : ss << argValue; - ss >> *value; - - int64_t min = arg.min; - int64_t max = chip::CanCastTo(arg.max) ? static_cast(arg.max) : INT64_MAX; - return (!ss.fail() && ss.eof() && *value >= min && *value <= max); - }); - break; - } - - case ArgumentType::Number_int32: { - isValidArgument = HandleNullableOptional(arg, argValue, [&](auto * value) { - std::stringstream ss; - isHexNotation ? ss << std::hex << argValue : ss << argValue; - ss >> *value; - - int64_t min = arg.min; - int64_t max = chip::CanCastTo(arg.max) ? static_cast(arg.max) : INT64_MAX; - return (!ss.fail() && ss.eof() && *value >= min && *value <= max); - }); - break; - } - - case ArgumentType::Number_int64: { - isValidArgument = HandleNullableOptional(arg, argValue, [&](auto * value) { - std::stringstream ss; - isHexNotation ? ss << std::hex << argValue : ss << argValue; - ss >> *value; - - int64_t min = arg.min; - int64_t max = chip::CanCastTo(arg.max) ? static_cast(arg.max) : INT64_MAX; - return (!ss.fail() && ss.eof() && *value >= min && *value <= max); - }); - break; - } - - case ArgumentType::Float: { - isValidArgument = HandleNullableOptional(arg, argValue, [&](auto * value) { - std::stringstream ss; - ss << argValue; - ss >> *value; - return (!ss.fail() && ss.eof()); - }); - break; - } - - case ArgumentType::Double: { - isValidArgument = HandleNullableOptional(arg, argValue, [&](auto * value) { - std::stringstream ss; - ss << argValue; - ss >> *value; - return (!ss.fail() && ss.eof()); - }); - break; - } - - case ArgumentType::Address: { - isValidArgument = HandleNullableOptional( - arg, argValue, [&](auto * value) { return ParseAddressWithInterface(argValue, value); }); - break; - } - } - - if (!isValidArgument) - { - ChipLogError(chipTool, "InitArgs: Invalid argument %s: %s", arg.name, argValue); - } - - return isValidArgument; -} - -size_t Command::AddArgument(const char * name, const char * value, uint8_t flags) -{ - Argument arg; - arg.type = ArgumentType::Attribute; - arg.name = name; - arg.value = const_cast(reinterpret_cast(value)); - arg.flags = flags; - - return AddArgumentToList(std::move(arg)); -} - -size_t Command::AddArgument(const char * name, char ** value, uint8_t flags) -{ - Argument arg; - arg.type = ArgumentType::String; - arg.name = name; - arg.value = reinterpret_cast(value); - arg.flags = flags; - - return AddArgumentToList(std::move(arg)); -} - -size_t Command::AddArgument(const char * name, chip::CharSpan * value, uint8_t flags) -{ - Argument arg; - arg.type = ArgumentType::CharString; - arg.name = name; - arg.value = reinterpret_cast(value); - arg.flags = flags; - - return AddArgumentToList(std::move(arg)); -} - -size_t Command::AddArgument(const char * name, chip::ByteSpan * value, uint8_t flags) -{ - Argument arg; - arg.type = ArgumentType::OctetString; - arg.name = name; - arg.value = reinterpret_cast(value); - arg.flags = flags; - - return AddArgumentToList(std::move(arg)); -} - -size_t Command::AddArgument(const char * name, AddressWithInterface * out, uint8_t flags) -{ - Argument arg; - arg.type = ArgumentType::Address; - arg.name = name; - arg.value = reinterpret_cast(out); - arg.flags = flags; - - return AddArgumentToList(std::move(arg)); -} - -size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, std::vector * value) -{ - Argument arg; - arg.type = ArgumentType::Vector16; - arg.name = name; - arg.value = static_cast(value); - arg.min = min; - arg.max = max; - arg.flags = 0; - - return AddArgumentToList(std::move(arg)); -} - -size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, std::vector * value) -{ - Argument arg; - arg.type = ArgumentType::Vector32; - arg.name = name; - arg.value = static_cast(value); - arg.min = min; - arg.max = max; - arg.flags = 0; - - 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; - arg.type = ArgumentType::Complex; - arg.name = name; - arg.value = static_cast(value); - arg.flags = 0; - - return AddArgumentToList(std::move(arg)); -} - -size_t Command::AddArgument(const char * name, CustomArgument * value) -{ - Argument arg; - arg.type = ArgumentType::Custom; - arg.name = name; - arg.value = const_cast(reinterpret_cast(value)); - arg.flags = 0; - - return AddArgumentToList(std::move(arg)); -} - -size_t Command::AddArgument(const char * name, float min, float max, float * out, uint8_t flags) -{ - Argument arg; - arg.type = ArgumentType::Float; - arg.name = name; - arg.value = reinterpret_cast(out); - arg.flags = flags; - // Ignore min/max for now; they're always +-Infinity anyway. - - return AddArgumentToList(std::move(arg)); -} - -size_t Command::AddArgument(const char * name, double min, double max, double * out, uint8_t flags) -{ - Argument arg; - arg.type = ArgumentType::Double; - arg.name = name; - arg.value = reinterpret_cast(out); - arg.flags = flags; - // Ignore min/max for now; they're always +-Infinity anyway. - - return AddArgumentToList(std::move(arg)); -} - -size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void * out, ArgumentType type, uint8_t flags) -{ - Argument arg; - arg.type = type; - arg.name = name; - arg.value = out; - arg.min = min; - arg.max = max; - arg.flags = flags; - - return AddArgumentToList(std::move(arg)); -} - -size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void * out, uint8_t flags) -{ - Argument arg; - arg.type = ArgumentType::Number_uint8; - arg.name = name; - arg.value = out; - arg.min = min; - arg.max = max; - arg.flags = flags; - - return AddArgumentToList(std::move(arg)); -} - -const char * Command::GetArgumentName(size_t index) const -{ - if (index < mArgs.size()) - { - return mArgs.at(index).name; - } - - return nullptr; -} - -const char * Command::GetAttribute(void) const -{ - size_t argsCount = mArgs.size(); - for (size_t i = 0; i < argsCount; i++) - { - Argument arg = mArgs.at(i); - if (arg.type == ArgumentType::Attribute) - { - return reinterpret_cast(arg.value); - } - } - - return nullptr; -} - -const char * Command::GetEvent(void) const -{ - size_t argsCount = mArgs.size(); - for (size_t i = 0; i < argsCount; i++) - { - Argument arg = mArgs.at(i); - if (arg.type == ArgumentType::Attribute) - { - return reinterpret_cast(arg.value); - } - } - - return nullptr; -} - -size_t Command::AddArgumentToList(Argument && argument) -{ - if (argument.isOptional() || mArgs.empty() || !mArgs.back().isOptional()) - { - // Safe to just append. - mArgs.emplace_back(std::move(argument)); - return mArgs.size(); - } - - // We're inserting a non-optional arg but we already have something optional - // in the list. Insert before the first optional arg. - for (auto cur = mArgs.cbegin(), end = mArgs.cend(); cur != end; ++cur) - { - if ((*cur).isOptional()) - { - mArgs.emplace(cur, std::move(argument)); - return mArgs.size(); - } - } - - // Never reached. - VerifyOrDie(false); - return 0; -} - -void Command::ResetArguments() -{ - ChipLogError(AppServer, " -- Command::ResetArguments"); - for (size_t i = 0; i < mArgs.size(); i++) - { - const Argument arg = mArgs[i]; - const ArgumentType type = arg.type; - const uint8_t flags = arg.flags; - if (type == ArgumentType::Vector16 && flags != Argument::kOptional) - { - auto vectorArgument = static_cast *>(arg.value); - vectorArgument->clear(); - } - else if (type == ArgumentType::Vector32 && flags != Argument::kOptional) - { - auto vectorArgument = static_cast *>(arg.value); - vectorArgument->clear(); - } - else if (type == ArgumentType::Vector32 && flags == Argument::kOptional) - { - auto optionalArgument = static_cast> *>(arg.value); - if (optionalArgument->HasValue()) - { - optionalArgument->Value().clear(); - } - } - } -} diff --git a/examples/tv-casting-app/tv-casting-common/commands/common/Command.h b/examples/tv-casting-app/tv-casting-common/commands/common/Command.h deleted file mode 100644 index 975c90297affc4..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/common/Command.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2020 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -#include "../clusters/ComplexArgument.h" -#include "../clusters/CustomArgument.h" -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -class Command; - -template -std::unique_ptr make_unique(Args &&... args) -{ - return std::unique_ptr(new T(std::forward(args)...)); -} - -struct movable_initializer_list -{ - movable_initializer_list(std::unique_ptr && in) : item(std::move(in)) {} - operator std::unique_ptr() const && { return std::move(item); } - mutable std::unique_ptr item; -}; - -typedef std::initializer_list commands_list; - -enum ArgumentType -{ - Number_uint8, - Number_uint16, - Number_uint32, - Number_uint64, - Number_int8, - Number_int16, - Number_int32, - Number_int64, - Float, - Double, - Bool, - String, - CharString, - OctetString, - Attribute, - Address, - Complex, - Custom, - Vector16, - Vector32, -}; - -struct Argument -{ - const char * name; - ArgumentType type; - int64_t min; - uint64_t max; - void * value; - uint8_t flags; - - enum - { - kOptional = (1 << 0), - kNullable = (1 << 1), - }; - - bool isOptional() const { return flags & kOptional; } - bool isNullable() const { return flags & kNullable; } -}; - -class Command -{ -public: - struct AddressWithInterface - { - ::chip::Inet::IPAddress address; - ::chip::Inet::InterfaceId interfaceId; - }; - - Command(const char * commandName) : mName(commandName) {} - virtual ~Command() {} - - const char * GetName(void) const { return mName; } - const char * GetAttribute(void) const; - const char * GetEvent(void) const; - const char * GetArgumentName(size_t index) const; - bool GetArgumentIsOptional(size_t index) const { return mArgs[index].isOptional(); } - size_t GetArgumentsCount(void) const { return mArgs.size(); } - - bool InitArguments(int argc, char ** argv); - size_t AddArgument(const char * name, const char * value, uint8_t flags = 0); - /** - * @brief - * Add a char string command argument - * - * @param name The name that will be displayed in the command help - * @param value A pointer to a `char *` where the argv value will be stored - * @returns The number of arguments currently added to the command - */ - size_t AddArgument(const char * name, char ** value, uint8_t flags = 0); - - /** - * Add an octet string command argument - */ - size_t AddArgument(const char * name, chip::ByteSpan * value, uint8_t flags = 0); - size_t AddArgument(const char * name, chip::Span * value, uint8_t flags = 0); - size_t AddArgument(const char * name, AddressWithInterface * out, uint8_t flags = 0); - size_t AddArgument(const char * name, ComplexArgument * value); - size_t AddArgument(const char * name, CustomArgument * value); - size_t AddArgument(const char * name, int64_t min, uint64_t max, bool * out, uint8_t flags = 0) - { - return AddArgument(name, min, max, reinterpret_cast(out), Bool, flags); - } - size_t AddArgument(const char * name, int64_t min, uint64_t max, int8_t * out, uint8_t flags = 0) - { - return AddArgument(name, min, max, reinterpret_cast(out), Number_int8, flags); - } - size_t AddArgument(const char * name, int64_t min, uint64_t max, int16_t * out, uint8_t flags = 0) - { - return AddArgument(name, min, max, reinterpret_cast(out), Number_int16, flags); - } - size_t AddArgument(const char * name, int64_t min, uint64_t max, int32_t * out, uint8_t flags = 0) - { - return AddArgument(name, min, max, reinterpret_cast(out), Number_int32, flags); - } - size_t AddArgument(const char * name, int64_t min, uint64_t max, int64_t * out, uint8_t flags = 0) - { - return AddArgument(name, min, max, reinterpret_cast(out), Number_int64, flags); - } - size_t AddArgument(const char * name, int64_t min, uint64_t max, uint8_t * out, uint8_t flags = 0) - { - return AddArgument(name, min, max, reinterpret_cast(out), Number_uint8, flags); - } - size_t AddArgument(const char * name, int64_t min, uint64_t max, uint16_t * out, uint8_t flags = 0) - { - return AddArgument(name, min, max, reinterpret_cast(out), Number_uint16, flags); - } - size_t AddArgument(const char * name, int64_t min, uint64_t max, uint32_t * out, uint8_t flags = 0) - { - return AddArgument(name, min, max, reinterpret_cast(out), Number_uint32, flags); - } - size_t AddArgument(const char * name, int64_t min, uint64_t max, uint64_t * out, uint8_t flags = 0) - { - return AddArgument(name, min, max, reinterpret_cast(out), Number_uint64, flags); - } - - size_t AddArgument(const char * name, float min, float max, float * out, uint8_t flags = 0); - size_t AddArgument(const char * name, double min, double max, double * out, uint8_t flags = 0); - - 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) - { - return AddArgument(name, min, max, reinterpret_cast *>(out), flags); - } - - template - size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::BitFlags * out, uint8_t flags = 0) - { - // This is a terrible hack that relies on BitFlags only having the one - // mValue member. - return AddArgument(name, min, max, reinterpret_cast(out), flags); - } - - template - size_t AddArgument(const char * name, chip::Optional * value) - { - return AddArgument(name, reinterpret_cast(value), Argument::kOptional); - } - - template - size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional * value) - { - return AddArgument(name, min, max, reinterpret_cast(value), Argument::kOptional); - } - - template - size_t AddArgument(const char * name, chip::app::DataModel::Nullable * value, uint8_t flags = 0) - { - return AddArgument(name, reinterpret_cast(value), flags | Argument::kNullable); - } - - template - size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::app::DataModel::Nullable * value, uint8_t flags = 0) - { - return AddArgument(name, min, max, reinterpret_cast(value), flags | Argument::kNullable); - } - - size_t AddArgument(const char * name, float min, float max, chip::app::DataModel::Nullable * value, uint8_t flags = 0) - { - return AddArgument(name, min, max, reinterpret_cast(value), flags | Argument::kNullable); - } - - size_t AddArgument(const char * name, double min, double max, chip::app::DataModel::Nullable * value, uint8_t flags = 0) - { - return AddArgument(name, min, max, reinterpret_cast(value), flags | Argument::kNullable); - } - - void ResetArguments(); - - virtual CHIP_ERROR Run() = 0; - - bool IsInteractive() { return mIsInteractive; } - - CHIP_ERROR RunAsInteractive() - { - mIsInteractive = true; - return Run(); - } - -private: - bool InitArgument(size_t argIndex, char * argValue); - size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, ArgumentType type, uint8_t flags); - size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, uint8_t flags); - - /** - * Add the Argument to our list. This preserves the property that all - * optional arguments come at the end of the list. - */ - size_t AddArgumentToList(Argument && argument); - - const char * mName = nullptr; - bool mIsInteractive = false; - std::vector mArgs; -}; diff --git a/examples/tv-casting-app/tv-casting-common/commands/common/Commands.cpp b/examples/tv-casting-app/tv-casting-common/commands/common/Commands.cpp deleted file mode 100644 index 0fbaeeefe7b199..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/common/Commands.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (c) 2020 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#include "Commands.h" - -#include "Command.h" - -#include -#include - -#include -#include - -void Commands::Register(const char * clusterName, commands_list commandsList) -{ - for (auto & command : commandsList) - { - mClusters[clusterName].push_back(std::move(command)); - } -} - -int Commands::Run(int argc, char ** argv) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - err = chip::Platform::MemoryInit(); - VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init Memory failure: %s", chip::ErrorStr(err))); - - // err = mStorage.Init(); - // VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init Storage failure: %s", chip::ErrorStr(err))); - - // chip::Logging::SetLogFilter(mStorage.GetLoggingLevel()); - - err = RunCommand(argc, argv); - VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(chipTool, "Run command failure: %s", chip::ErrorStr(err))); - -exit: - return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; -} - -int Commands::RunInteractive(int argc, char ** argv) -{ - CHIP_ERROR err = RunCommand(argc, argv, true); - return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; -} - -CHIP_ERROR Commands::RunCommand(int argc, char ** argv, bool interactive) -{ - std::map::iterator cluster; - Command * command = nullptr; - - if (argc <= 1) - { - ChipLogError(chipTool, "Missing cluster name"); - ShowClusters(argv[0]); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - cluster = GetCluster(argv[1]); - if (cluster == mClusters.end()) - { - ChipLogError(chipTool, "Unknown cluster: %s", argv[1]); - ShowClusters(argv[0]); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - if (argc <= 2) - { - ChipLogError(chipTool, "Missing command name"); - ShowCluster(argv[0], argv[1], cluster->second); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - if (!IsGlobalCommand(argv[2])) - { - command = GetCommand(cluster->second, argv[2]); - if (command == nullptr) - { - ChipLogError(chipTool, "Unknown command: %s", argv[2]); - ShowCluster(argv[0], argv[1], cluster->second); - return CHIP_ERROR_INVALID_ARGUMENT; - } - } - else if (IsEventCommand(argv[2])) - { - if (argc <= 3) - { - ChipLogError(chipTool, "Missing event name"); - ShowClusterEvents(argv[0], argv[1], argv[2], cluster->second); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - command = GetGlobalCommand(cluster->second, argv[2], argv[3]); - if (command == nullptr) - { - ChipLogError(chipTool, "Unknown event: %s", argv[3]); - ShowClusterEvents(argv[0], argv[1], argv[2], cluster->second); - return CHIP_ERROR_INVALID_ARGUMENT; - } - } - else - { - if (argc <= 3) - { - ChipLogError(chipTool, "Missing attribute name"); - ShowClusterAttributes(argv[0], argv[1], argv[2], cluster->second); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - command = GetGlobalCommand(cluster->second, argv[2], argv[3]); - if (command == nullptr) - { - ChipLogError(chipTool, "Unknown attribute: %s", argv[3]); - ShowClusterAttributes(argv[0], argv[1], argv[2], cluster->second); - return CHIP_ERROR_INVALID_ARGUMENT; - } - } - - if (!command->InitArguments(argc - 3, &argv[3])) - { - ShowCommand(argv[0], argv[1], command); - return CHIP_ERROR_INVALID_ARGUMENT; - } - - return interactive ? command->RunAsInteractive() : command->Run(); -} - -std::map::iterator Commands::GetCluster(std::string clusterName) -{ - for (auto & cluster : mClusters) - { - std::string key(cluster.first); - std::transform(key.begin(), key.end(), key.begin(), ::tolower); - if (key.compare(clusterName) == 0) - { - return mClusters.find(cluster.first); - } - } - - return mClusters.end(); -} - -Command * Commands::GetCommand(CommandsVector & commands, std::string commandName) -{ - for (auto & command : commands) - { - if (commandName.compare(command->GetName()) == 0) - { - return command.get(); - } - } - - return nullptr; -} - -Command * Commands::GetGlobalCommand(CommandsVector & commands, std::string commandName, std::string attributeName) -{ - for (auto & command : commands) - { - if (commandName.compare(command->GetName()) == 0 && attributeName.compare(command->GetAttribute()) == 0) - { - return command.get(); - } - } - - return nullptr; -} - -bool Commands::IsAttributeCommand(std::string commandName) const -{ - return commandName.compare("read") == 0 || commandName.compare("write") == 0 || commandName.compare("subscribe") == 0; -} - -bool Commands::IsEventCommand(std::string commandName) const -{ - return commandName.compare("read-event") == 0 || commandName.compare("subscribe-event") == 0; -} - -bool Commands::IsGlobalCommand(std::string commandName) const -{ - return IsAttributeCommand(commandName) || IsEventCommand(commandName); -} - -void Commands::ShowClusters(std::string executable) -{ - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s cluster_name command_name [param1 param2 ...]\n", executable.c_str()); - fprintf(stderr, "\n"); - fprintf(stderr, " +-------------------------------------------------------------------------------------+\n"); - fprintf(stderr, " | Clusters: |\n"); - fprintf(stderr, " +-------------------------------------------------------------------------------------+\n"); - for (auto & cluster : mClusters) - { - std::string clusterName(cluster.first); - std::transform(clusterName.begin(), clusterName.end(), clusterName.begin(), - [](unsigned char c) { return std::tolower(c); }); - fprintf(stderr, " | * %-82s|\n", clusterName.c_str()); - } - fprintf(stderr, " +-------------------------------------------------------------------------------------+\n"); -} - -void Commands::ShowCluster(std::string executable, std::string clusterName, CommandsVector & commands) -{ - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s %s command_name [param1 param2 ...]\n", executable.c_str(), clusterName.c_str()); - fprintf(stderr, "\n"); - fprintf(stderr, " +-------------------------------------------------------------------------------------+\n"); - fprintf(stderr, " | Commands: |\n"); - fprintf(stderr, " +-------------------------------------------------------------------------------------+\n"); - bool readCommand = false; - bool writeCommand = false; - bool subscribeCommand = false; - bool readEventCommand = false; - bool subscribeEventCommand = false; - for (auto & command : commands) - { - bool shouldPrint = true; - - if (IsGlobalCommand(command->GetName())) - { - if (strcmp(command->GetName(), "read") == 0 && !readCommand) - { - readCommand = true; - } - else if (strcmp(command->GetName(), "write") == 0 && !writeCommand) - { - writeCommand = true; - } - else if (strcmp(command->GetName(), "subscribe") == 0 && !subscribeCommand) - { - subscribeCommand = true; - } - else if (strcmp(command->GetName(), "read-event") == 0 && !readEventCommand) - { - readEventCommand = true; - } - else if (strcmp(command->GetName(), "subscribe-event") == 0 && !subscribeEventCommand) - { - subscribeEventCommand = true; - } - else - { - shouldPrint = false; - } - } - - if (shouldPrint) - { - fprintf(stderr, " | * %-82s|\n", command->GetName()); - } - } - fprintf(stderr, " +-------------------------------------------------------------------------------------+\n"); -} - -void Commands::ShowClusterAttributes(std::string executable, std::string clusterName, std::string commandName, - CommandsVector & commands) -{ - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s %s %s attribute-name [param1 param2 ...]\n", executable.c_str(), clusterName.c_str(), - commandName.c_str()); - fprintf(stderr, "\n"); - fprintf(stderr, " +-------------------------------------------------------------------------------------+\n"); - fprintf(stderr, " | Attributes: |\n"); - fprintf(stderr, " +-------------------------------------------------------------------------------------+\n"); - for (auto & command : commands) - { - if (commandName.compare(command->GetName()) == 0) - { - fprintf(stderr, " | * %-82s|\n", command->GetAttribute()); - } - } - fprintf(stderr, " +-------------------------------------------------------------------------------------+\n"); -} - -void Commands::ShowClusterEvents(std::string executable, std::string clusterName, std::string commandName, - CommandsVector & commands) -{ - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s %s %s event-name [param1 param2 ...]\n", executable.c_str(), clusterName.c_str(), commandName.c_str()); - fprintf(stderr, "\n"); - fprintf(stderr, " +-------------------------------------------------------------------------------------+\n"); - fprintf(stderr, " | Events: |\n"); - fprintf(stderr, " +-------------------------------------------------------------------------------------+\n"); - for (auto & command : commands) - { - if (commandName.compare(command->GetName()) == 0) - { - fprintf(stderr, " | * %-82s|\n", command->GetEvent()); - } - } - fprintf(stderr, " +-------------------------------------------------------------------------------------+\n"); -} - -void Commands::ShowCommand(std::string executable, std::string clusterName, Command * command) -{ - fprintf(stderr, "Usage:\n"); - - std::string arguments; - arguments += command->GetName(); - - size_t argumentsCount = command->GetArgumentsCount(); - for (size_t i = 0; i < argumentsCount; i++) - { - arguments += " "; - bool isOptional = command->GetArgumentIsOptional(i); - if (isOptional) - { - arguments += "[--"; - } - arguments += command->GetArgumentName(i); - if (isOptional) - { - arguments += "]"; - } - } - fprintf(stderr, " %s %s %s\n", executable.c_str(), clusterName.c_str(), arguments.c_str()); -} diff --git a/examples/tv-casting-app/tv-casting-common/commands/common/Commands.h b/examples/tv-casting-app/tv-casting-common/commands/common/Commands.h deleted file mode 100644 index a179bc33e53ff7..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/common/Commands.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2020 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -// #include "../../config/PersistentStorage.h" -#include "Command.h" -#include - -class Commands -{ -public: - using CommandsVector = ::std::vector>; - - void Register(const char * clusterName, commands_list commandsList); - int Run(int argc, char ** argv); - int RunInteractive(int argc, char ** argv); - -private: - CHIP_ERROR RunCommand(int argc, char ** argv, bool interactive = false); - - std::map::iterator GetCluster(std::string clusterName); - Command * GetCommand(CommandsVector & commands, std::string commandName); - Command * GetGlobalCommand(CommandsVector & commands, std::string commandName, std::string attributeName); - bool IsAttributeCommand(std::string commandName) const; - bool IsEventCommand(std::string commandName) const; - bool IsGlobalCommand(std::string commandName) const; - - void ShowClusters(std::string executable); - void ShowCluster(std::string executable, std::string clusterName, CommandsVector & commands); - void ShowClusterAttributes(std::string executable, std::string clusterName, std::string commandName, CommandsVector & commands); - void ShowClusterEvents(std::string executable, std::string clusterName, std::string commandName, CommandsVector & commands); - void ShowCommand(std::string executable, std::string clusterName, Command * command); - - std::map mClusters; - // PersistentStorage mStorage; -}; diff --git a/examples/tv-casting-app/tv-casting-common/commands/common/CredentialIssuerCommands.h b/examples/tv-casting-app/tv-casting-common/commands/common/CredentialIssuerCommands.h deleted file mode 100644 index 951ef86efceb40..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/common/CredentialIssuerCommands.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2021-2022 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -#include -#include -#include -#include -#include - -class CredentialIssuerCommands -{ -public: - virtual ~CredentialIssuerCommands() {} - - /** - * @brief - * This function is used to initialize the Credentials Issuer, if needed. - * - * @param[in] storage A reference to the storage, where the Credentials Issuer can optionally use to access the keypair in - * storage. - * - * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code. - */ - virtual CHIP_ERROR InitializeCredentialsIssuer(chip::PersistentStorageDelegate & storage) = 0; - - /** - * @brief - * This function is used to setup Device Attestation Singletons and intialize Setup/Commissioning Parameters with a custom - * Device Attestation Verifier object. - * - * @param[in] setupParams A reference to the Setup/Commissioning Parameters, to be initialized with custom Device Attestation - * Verifier. - * @param[in] trustStore A pointer to the PAA trust store to use to find valid PAA roots. - * - * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code. - */ - virtual CHIP_ERROR SetupDeviceAttestation(chip::Controller::SetupParams & setupParams, - const chip::Credentials::AttestationTrustStore * trustStore) = 0; - - virtual chip::Controller::OperationalCredentialsDelegate * GetCredentialIssuer() = 0; - - /** - * @brief - * This function is used to Generate NOC Chain for the Controller/Commissioner. Parameters follow the example implementation, - * so some parameters may not translate to the real remote Credentials Issuer policy. - * - * @param[in] nodeId The desired NodeId for the generated NOC Chain - May be optional/unused in some implementations. - * @param[in] fabricId The desired FabricId for the generated NOC Chain - May be optional/unused in some implementations. - * @param[in] cats The desired CATs for the generated NOC Chain - May be optional/unused in some implementations. - * @param[in] keypair The desired Keypair for the generated NOC Chain - May be optional/unused in some implementations. - * @param[in,out] rcac Buffer to hold the Root Certificate of the generated NOC Chain. - * @param[in,out] icac Buffer to hold the Intermediate Certificate of the generated NOC Chain. - * @param[in,out] noc Buffer to hold the Leaf Certificate of the generated NOC Chain. - * - * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code. - */ - virtual CHIP_ERROR GenerateControllerNOCChain(chip::NodeId nodeId, chip::FabricId fabricId, const chip::CATValues & cats, - chip::Crypto::P256Keypair & keypair, chip::MutableByteSpan & rcac, - chip::MutableByteSpan & icac, chip::MutableByteSpan & noc) = 0; -}; diff --git a/examples/tv-casting-app/tv-casting-common/commands/example/ExampleCredentialIssuerCommands.h b/examples/tv-casting-app/tv-casting-common/commands/example/ExampleCredentialIssuerCommands.h deleted file mode 100644 index 74646c8b5f10ba..00000000000000 --- a/examples/tv-casting-app/tv-casting-common/commands/example/ExampleCredentialIssuerCommands.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2021-2022 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -class ExampleCredentialIssuerCommands : public CredentialIssuerCommands -{ -public: - CHIP_ERROR InitializeCredentialsIssuer(chip::PersistentStorageDelegate & storage) override - { - return mOpCredsIssuer.Initialize(storage); - } - CHIP_ERROR SetupDeviceAttestation(chip::Controller::SetupParams & setupParams, - const chip::Credentials::AttestationTrustStore * trustStore) override - { - chip::Credentials::SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider()); - - setupParams.deviceAttestationVerifier = chip::Credentials::GetDefaultDACVerifier(trustStore); - - return CHIP_NO_ERROR; - } - chip::Controller::OperationalCredentialsDelegate * GetCredentialIssuer() override { return &mOpCredsIssuer; } - CHIP_ERROR GenerateControllerNOCChain(chip::NodeId nodeId, chip::FabricId fabricId, const chip::CATValues & cats, - chip::Crypto::P256Keypair & keypair, chip::MutableByteSpan & rcac, - chip::MutableByteSpan & icac, chip::MutableByteSpan & noc) override - { - return mOpCredsIssuer.GenerateNOCChainAfterValidation(nodeId, fabricId, cats, keypair.Pubkey(), rcac, icac, noc); - } - -private: - chip::Controller::ExampleOperationalCredentialsIssuer mOpCredsIssuer; -};