| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- /*
- * 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 <app/data-model/Nullable.h>
- #include <commands/clusters/ComplexArgument.h>
- #include <commands/clusters/CustomArgument.h>
- #include <inet/InetInterface.h>
- #include <lib/core/Optional.h>
- #include <lib/support/Span.h>
- #include <lib/support/logging/CHIPLogging.h>
- #include <atomic>
- #include <condition_variable>
- #include <memory>
- #include <mutex>
- #include <vector>
- class Command;
- template <typename T, typename... Args>
- std::unique_ptr<Command> make_unique(Args &&... args)
- {
- return std::unique_ptr<Command>(new T(std::forward<Args>(args)...));
- }
- struct movable_initializer_list
- {
- movable_initializer_list(std::unique_ptr<Command> && in) : item(std::move(in)) {}
- operator std::unique_ptr<Command>() const && { return std::move(item); }
- mutable std::unique_ptr<Command> item;
- };
- typedef std::initializer_list<movable_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,
- Address,
- Complex,
- Custom,
- VectorBool,
- Vector16,
- Vector32,
- VectorCustom,
- VectorString, // comma separated string items
- };
- struct Argument
- {
- const char * name;
- ArgumentType type;
- int64_t min;
- uint64_t max;
- void * value;
- uint8_t flags;
- const char * desc;
- enum
- {
- kOptional = (1 << 0),
- kNullable = (1 << 1),
- };
- bool isOptional() const { return flags & kOptional; }
- bool isNullable() const { return flags & kNullable; }
- };
- struct ReadOnlyGlobalCommandArgument
- {
- const char * name;
- const char * value;
- const char * desc;
- };
- class Command
- {
- public:
- struct AddressWithInterface
- {
- ::chip::Inet::IPAddress address;
- ::chip::Inet::InterfaceId interfaceId;
- };
- Command(const char * commandName, const char * helpText = nullptr) : mName(commandName), mHelpText(helpText) {}
- virtual ~Command() {}
- const char * GetName(void) const { return mName; }
- const char * GetHelpText() const { return mHelpText; }
- const char * GetReadOnlyGlobalCommandArgument(void) const;
- const char * GetAttribute(void) const;
- const char * GetEvent(void) const;
- const char * GetArgumentName(size_t index) const;
- const char * GetArgumentDescription(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);
- void AddArgument(const char * name, const char * value, const char * desc = "");
- /**
- * @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
- * @param flags
- * @param desc The description of the argument that will be displayed in the command help
- * @returns The number of arguments currently added to the command
- */
- size_t AddArgument(const char * name, char ** value, const char * desc = "", uint8_t flags = 0);
- /**
- * Add an octet string command argument
- */
- size_t AddArgument(const char * name, chip::ByteSpan * value, const char * desc = "", uint8_t flags = 0);
- size_t AddArgument(const char * name, chip::Span<const char> * value, const char * desc = "", uint8_t flags = 0);
- size_t AddArgument(const char * name, AddressWithInterface * out, const char * desc = "", uint8_t flags = 0);
- // Optional Complex arguments are not currently supported via the <chip::Optional> class.
- // Instead, they must be explicitly specified as optional using kOptional in the flags parameter,
- // and the base TypedComplexArgument<T> class is referenced.
- size_t AddArgument(const char * name, ComplexArgument * value, const char * desc = "", uint8_t flags = 0);
- size_t AddArgument(const char * name, CustomArgument * value, const char * desc = "");
- size_t AddArgument(const char * name, int64_t min, uint64_t max, bool * out, const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, min, max, reinterpret_cast<void *>(out), Bool, desc, flags);
- }
- size_t AddArgument(const char * name, int64_t min, uint64_t max, int8_t * out, const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int8, desc, flags);
- }
- size_t AddArgument(const char * name, int64_t min, uint64_t max, int16_t * out, const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int16, desc, flags);
- }
- size_t AddArgument(const char * name, int64_t min, uint64_t max, int32_t * out, const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int32, desc, flags);
- }
- size_t AddArgument(const char * name, int64_t min, uint64_t max, int64_t * out, const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int64, desc, flags);
- }
- size_t AddArgument(const char * name, int64_t min, uint64_t max, uint8_t * out, const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint8, desc, flags);
- }
- size_t AddArgument(const char * name, int64_t min, uint64_t max, uint16_t * out, const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint16, desc, flags);
- }
- size_t AddArgument(const char * name, int64_t min, uint64_t max, uint32_t * out, const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint32, desc, flags);
- }
- size_t AddArgument(const char * name, int64_t min, uint64_t max, uint64_t * out, const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint64, desc, flags);
- }
- size_t AddArgument(const char * name, float min, float max, float * out, const char * desc = "", uint8_t flags = 0);
- size_t AddArgument(const char * name, double min, double max, double * out, const char * desc = "", uint8_t flags = 0);
- size_t AddArgument(const char * name, int64_t min, uint64_t max, std::vector<uint16_t> * value, const char * desc = "");
- size_t AddArgument(const char * name, int64_t min, uint64_t max, std::vector<uint32_t> * value, const char * desc = "");
- size_t AddArgument(const char * name, std::vector<CustomArgument *> * value, const char * desc = "");
- size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<std::vector<bool>> * value,
- const char * desc = "");
- size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<std::vector<uint32_t>> * value,
- const char * desc = "");
- template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
- size_t AddArgument(const char * name, int64_t min, uint64_t max, T * out, const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, min, max, reinterpret_cast<std::underlying_type_t<T> *>(out), desc, flags);
- }
- template <typename T>
- size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::BitFlags<T> * out, const char * desc = "",
- 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<T *>(out), desc, flags);
- }
- template <typename T>
- size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::BitMask<T> * out, const char * desc = "",
- uint8_t flags = 0)
- {
- // This is a terrible hack that relies on BitMask only having the one
- // mValue member.
- return AddArgument(name, min, max, reinterpret_cast<T *>(out), desc, flags);
- }
- template <typename T>
- size_t AddArgument(const char * name, chip::Optional<T> * value, const char * desc = "")
- {
- return AddArgument(name, reinterpret_cast<T *>(value), desc, Argument::kOptional);
- }
- template <typename T>
- size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<T> * value, const char * desc = "")
- {
- return AddArgument(name, min, max, reinterpret_cast<T *>(value), desc, Argument::kOptional);
- }
- template <typename T>
- size_t AddArgument(const char * name, chip::app::DataModel::Nullable<T> * value, const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, reinterpret_cast<T *>(value), desc, flags | Argument::kNullable);
- }
- template <typename T>
- size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::app::DataModel::Nullable<T> * value,
- const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, min, max, reinterpret_cast<T *>(value), desc, flags | Argument::kNullable);
- }
- size_t AddArgument(const char * name, float min, float max, chip::app::DataModel::Nullable<float> * value,
- const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, min, max, reinterpret_cast<float *>(value), desc, flags | Argument::kNullable);
- }
- size_t AddArgument(const char * name, double min, double max, chip::app::DataModel::Nullable<double> * value,
- const char * desc = "", uint8_t flags = 0)
- {
- return AddArgument(name, min, max, reinterpret_cast<double *>(value), desc, flags | Argument::kNullable);
- }
- size_t AddArgument(const char * name, std::vector<std::string> * value, const char * desc);
- size_t AddArgument(const char * name, chip::Optional<std::vector<std::string>> * value, const char * desc);
- void ResetArguments();
- virtual CHIP_ERROR Run() = 0;
- bool IsInteractive() { return mIsInteractive; }
- CHIP_ERROR RunAsInteractive(const chip::Optional<char *> & interactiveStorageDirectory)
- {
- mStorageDirectory = interactiveStorageDirectory;
- mIsInteractive = true;
- return Run();
- }
- const chip::Optional<char *> & GetStorageDirectory() const { return mStorageDirectory; }
- protected:
- // mStorageDirectory lives here so we can just set it in RunAsInteractive.
- chip::Optional<char *> mStorageDirectory;
- private:
- bool InitArgument(size_t argIndex, char * argValue);
- size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, ArgumentType type, const char * desc,
- uint8_t flags);
- size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, const char * desc, 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;
- const char * mHelpText = nullptr;
- bool mIsInteractive = false;
- chip::Optional<ReadOnlyGlobalCommandArgument> mReadOnlyGlobalCommandArgument;
- std::vector<Argument> mArgs;
- };
|