Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / examples / chip-tool / commands / common / Command.h
1 /*
2  *   Copyright (c) 2020 Project CHIP Authors
3  *   All rights reserved.
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  *
17  */
18
19 #pragma once
20
21 #include <app/server/DataModelHandler.h>
22 #include <controller/CHIPDeviceController.h>
23 #include <inet/InetInterface.h>
24 #include <support/logging/CHIPLogging.h>
25
26 #include <atomic>
27 #include <condition_variable>
28 #include <memory>
29 #include <mutex>
30 #include <vector>
31
32 class Command;
33 class PersistentStorage;
34
35 template <typename T, typename... Args>
36 std::unique_ptr<Command> make_unique(Args &&... args)
37 {
38     return std::unique_ptr<Command>(new T(std::forward<Args>(args)...));
39 }
40
41 struct movable_initializer_list
42 {
43     movable_initializer_list(std::unique_ptr<Command> && in) : item(std::move(in)) {}
44     operator std::unique_ptr<Command>() const && { return std::move(item); }
45     mutable std::unique_ptr<Command> item;
46 };
47
48 typedef std::initializer_list<movable_initializer_list> commands_list;
49
50 enum ArgumentType
51 {
52     Number_uint8,
53     Number_uint16,
54     Number_uint32,
55     Number_uint64,
56     Number_int8,
57     Number_int16,
58     Number_int32,
59     Number_int64,
60     String,
61     Attribute,
62     Address
63 };
64
65 struct Argument
66 {
67     const char * name;
68     ArgumentType type;
69     int64_t min;
70     uint64_t max;
71     void * value;
72 };
73
74 class Command
75 {
76 public:
77     using ChipDeviceCommissioner = ::chip::Controller::DeviceCommissioner;
78     using ChipSerializedDevice   = ::chip::Controller::SerializedDevice;
79     using ChipDevice             = ::chip::Controller::Device;
80     using PeerAddress            = ::chip::Transport::PeerAddress;
81     using IPAddress              = ::chip::Inet::IPAddress;
82     using PacketBufferHandle     = ::chip::System::PacketBufferHandle;
83     using NodeId                 = ::chip::NodeId;
84
85     struct AddressWithInterface
86     {
87         ::chip::Inet::IPAddress address;
88         ::chip::Inet::InterfaceId interfaceId;
89     };
90
91     Command(const char * commandName) : mName(commandName) {}
92     virtual ~Command() {}
93
94     const char * GetName(void) const { return mName; }
95     const char * GetAttribute(void) const;
96     const char * GetArgumentName(size_t index) const;
97     size_t GetArgumentsCount(void) const { return mArgs.size(); }
98
99     bool InitArguments(int argc, char ** argv);
100     size_t AddArgument(const char * name, const char * value);
101     /**
102      * @brief
103      *   Add a string command argument
104      *
105      * @param name  The name that will be displayed in the command help
106      * @param value A pointer to a `char *` where the argv value will be stored
107      * @returns The number of arguments currently added to the command
108      */
109     size_t AddArgument(const char * name, char ** value);
110     size_t AddArgument(const char * name, AddressWithInterface * out);
111     size_t AddArgument(const char * name, int64_t min, uint64_t max, int8_t * out)
112     {
113         return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int8);
114     }
115     size_t AddArgument(const char * name, int64_t min, uint64_t max, int16_t * out)
116     {
117         return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int16);
118     }
119     size_t AddArgument(const char * name, int64_t min, uint64_t max, int32_t * out)
120     {
121         return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int32);
122     }
123     size_t AddArgument(const char * name, int64_t min, uint64_t max, int64_t * out)
124     {
125         return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int64);
126     }
127     size_t AddArgument(const char * name, int64_t min, uint64_t max, uint8_t * out)
128     {
129         return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint8);
130     }
131     size_t AddArgument(const char * name, int64_t min, uint64_t max, uint16_t * out)
132     {
133         return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint16);
134     }
135     size_t AddArgument(const char * name, int64_t min, uint64_t max, uint32_t * out)
136     {
137         return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint32);
138     }
139     size_t AddArgument(const char * name, int64_t min, uint64_t max, uint64_t * out)
140     {
141         return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint64);
142     }
143
144     virtual CHIP_ERROR Run(PersistentStorage & storage, NodeId localId, NodeId remoteId) = 0;
145
146     bool GetCommandExitStatus() const { return mCommandExitStatus; }
147     void SetCommandExitStatus(bool status)
148     {
149         mCommandExitStatus = status;
150         UpdateWaitForResponse(false);
151     }
152
153     void UpdateWaitForResponse(bool value);
154     void WaitForResponse(uint16_t duration);
155
156 private:
157     bool InitArgument(size_t argIndex, const char * argValue);
158     size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, ArgumentType type);
159     size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out);
160
161     bool mCommandExitStatus = false;
162     const char * mName      = nullptr;
163     std::vector<Argument> mArgs;
164
165     std::condition_variable cvWaitingForResponse;
166     std::mutex cvWaitingForResponseMutex;
167     bool mWaitingForResponse{ false };
168 };