Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / examples / chip-tool / commands / common / Commands.cpp
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 /* TIZEN_CHIP_MODIFY */
20
21 #include "Commands.h"
22
23 #include "Command.h"
24
25 #include <algorithm>
26 #include <string>
27
28 #if CONFIG_DEVICE_LAYER
29 #include <platform/CHIPDeviceLayer.h>
30 #endif
31
32 #include <support/CHIPMem.h>
33 #include <support/CodeUtils.h>
34
35 void Commands::Register(const char * clusterName, commands_list commandsList)
36 {
37     for (auto & command : commandsList)
38     {
39         mClusters[clusterName].push_back(std::move(command));
40     }
41 }
42
43 int Commands::Run(NodeId localId, NodeId remoteId, int argc, char ** argv)
44 {
45     CHIP_ERROR err = CHIP_NO_ERROR;
46     PersistentStorage storage;
47
48     err = chip::Platform::MemoryInit();
49     VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init Memory failure: %s", chip::ErrorStr(err)));
50
51 #if (CHIP_DEVICE_LAYER_TARGET_LINUX && CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE) || \
52     (CHIP_DEVICE_LAYER_TARGET_TIZEN && CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE)
53     // By default, Linux device is configured as a BLE peripheral while the controller needs a BLE central.
54     SuccessOrExit(err = chip::DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(/* BLE adapter ID */ 0, /* BLE central */ true));
55 #endif
56
57     err = storage.Init();
58     VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init Storage failure: %s", chip::ErrorStr(err)));
59
60     chip::Logging::SetLogFilter(storage.GetLoggingLevel());
61
62     err = RunCommand(storage, localId, remoteId, argc, argv);
63     SuccessOrExit(err);
64
65 exit:
66     return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE;
67 }
68
69 CHIP_ERROR Commands::RunCommand(PersistentStorage & storage, NodeId localId, NodeId remoteId, int argc, char ** argv)
70 {
71     CHIP_ERROR err = CHIP_NO_ERROR;
72     std::map<std::string, CommandsVector>::iterator cluster;
73     Command * command = nullptr;
74
75     if (argc <= 1)
76     {
77         ChipLogError(chipTool, "Missing cluster name");
78         ShowClusters(argv[0]);
79         ExitNow(err = CHIP_ERROR_INVALID_ARGUMENT);
80     }
81
82     cluster = GetCluster(argv[1]);
83     if (cluster == mClusters.end())
84     {
85         ChipLogError(chipTool, "Unknown cluster: %s", argv[1]);
86         ShowClusters(argv[0]);
87         ExitNow(err = CHIP_ERROR_INVALID_ARGUMENT);
88     }
89
90     if (argc <= 2)
91     {
92         ChipLogError(chipTool, "Missing command name");
93         ShowCluster(argv[0], argv[1], cluster->second);
94         ExitNow(err = CHIP_ERROR_INVALID_ARGUMENT);
95     }
96
97     if (!IsGlobalCommand(argv[2]))
98     {
99         command = GetCommand(cluster->second, argv[2]);
100         if (command == nullptr)
101         {
102             ChipLogError(chipTool, "Unknown command: %s", argv[2]);
103             ShowCluster(argv[0], argv[1], cluster->second);
104             ExitNow(err = CHIP_ERROR_INVALID_ARGUMENT);
105         }
106     }
107     else
108     {
109         if (argc <= 3)
110         {
111             ChipLogError(chipTool, "Missing attribute name");
112             ShowClusterAttributes(argv[0], argv[1], argv[2], cluster->second);
113             ExitNow(err = CHIP_ERROR_INVALID_ARGUMENT);
114         }
115
116         command = GetGlobalCommand(cluster->second, argv[2], argv[3]);
117         if (command == nullptr)
118         {
119             ChipLogError(chipTool, "Unknown attribute: %s", argv[3]);
120             ShowClusterAttributes(argv[0], argv[1], argv[2], cluster->second);
121             ExitNow(err = CHIP_ERROR_INVALID_ARGUMENT);
122         }
123     }
124
125     if (!command->InitArguments(argc - 3, &argv[3]))
126     {
127         ShowCommand(argv[0], argv[1], command);
128         ExitNow(err = CHIP_ERROR_INVALID_ARGUMENT);
129     }
130
131     err = command->Run(storage, localId, remoteId);
132     if (err != CHIP_NO_ERROR)
133     {
134         ChipLogError(chipTool, "Run command failure: %s", chip::ErrorStr(err));
135         ExitNow();
136     }
137
138 exit:
139     return err;
140 }
141
142 std::map<std::string, Commands::CommandsVector>::iterator Commands::GetCluster(std::string clusterName)
143 {
144     for (auto & cluster : mClusters)
145     {
146         std::string key(cluster.first);
147         std::transform(key.begin(), key.end(), key.begin(), ::tolower);
148         if (key.compare(clusterName) == 0)
149         {
150             return mClusters.find(cluster.first);
151         }
152     }
153
154     return mClusters.end();
155 }
156
157 Command * Commands::GetCommand(CommandsVector & commands, std::string commandName)
158 {
159     for (auto & command : commands)
160     {
161         if (commandName.compare(command->GetName()) == 0)
162         {
163             return command.get();
164         }
165     }
166
167     return nullptr;
168 }
169
170 Command * Commands::GetGlobalCommand(CommandsVector & commands, std::string commandName, std::string attributeName)
171 {
172     for (auto & command : commands)
173     {
174         if (commandName.compare(command->GetName()) == 0 && attributeName.compare(command->GetAttribute()) == 0)
175         {
176             return command.get();
177         }
178     }
179
180     return nullptr;
181 }
182
183 bool Commands::IsGlobalCommand(std::string commandName) const
184 {
185     return commandName.compare("read") == 0 || commandName.compare("write") == 0 || commandName.compare("report") == 0;
186 }
187
188 void Commands::ShowClusters(std::string executable)
189 {
190     fprintf(stderr, "Usage:\n");
191     fprintf(stderr, "  %s cluster_name command_name [param1 param2 ...]\n", executable.c_str());
192     fprintf(stderr, "\n");
193     fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
194     fprintf(stderr, "  | Clusters:                                                                           |\n");
195     fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
196     for (auto & cluster : mClusters)
197     {
198         std::string clusterName(cluster.first);
199         std::transform(clusterName.begin(), clusterName.end(), clusterName.begin(),
200                        [](unsigned char c) { return std::tolower(c); });
201         fprintf(stderr, "  | * %-82s|\n", clusterName.c_str());
202     }
203     fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
204 }
205
206 void Commands::ShowCluster(std::string executable, std::string clusterName, CommandsVector & commands)
207 {
208     fprintf(stderr, "Usage:\n");
209     fprintf(stderr, "  %s %s command_name [param1 param2 ...]\n", executable.c_str(), clusterName.c_str());
210     fprintf(stderr, "\n");
211     fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
212     fprintf(stderr, "  | Commands:                                                                           |\n");
213     fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
214     bool readCommand   = false;
215     bool writeCommand  = false;
216     bool reportCommand = false;
217     for (auto & command : commands)
218     {
219         bool shouldPrint = true;
220
221         if (IsGlobalCommand(command->GetName()))
222         {
223             if (strcmp(command->GetName(), "read") == 0 && readCommand == false)
224             {
225                 readCommand = true;
226             }
227             else if (strcmp(command->GetName(), "write") == 0 && writeCommand == false)
228             {
229                 writeCommand = true;
230             }
231             else if (strcmp(command->GetName(), "report") == 0 && reportCommand == false)
232             {
233                 reportCommand = true;
234             }
235             else
236             {
237                 shouldPrint = false;
238             }
239         }
240
241         if (shouldPrint)
242         {
243             fprintf(stderr, "  | * %-82s|\n", command->GetName());
244         }
245     }
246     fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
247 }
248
249 void Commands::ShowClusterAttributes(std::string executable, std::string clusterName, std::string commandName,
250                                      CommandsVector & commands)
251 {
252     fprintf(stderr, "Usage:\n");
253     fprintf(stderr, "  %s %s %s attribute-name [param1 param2 ...]\n", executable.c_str(), clusterName.c_str(),
254             commandName.c_str());
255     fprintf(stderr, "\n");
256     fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
257     fprintf(stderr, "  | Attributes:                                                                         |\n");
258     fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
259     for (auto & command : commands)
260     {
261         if (commandName.compare(command->GetName()) == 0)
262         {
263             fprintf(stderr, "  | * %-82s|\n", command->GetAttribute());
264         }
265     }
266     fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
267 }
268
269 void Commands::ShowCommand(std::string executable, std::string clusterName, Command * command)
270 {
271     fprintf(stderr, "Usage:\n");
272
273     std::string arguments = "";
274     arguments += command->GetName();
275
276     size_t argumentsCount = command->GetArgumentsCount();
277     for (size_t i = 0; i < argumentsCount; i++)
278     {
279         arguments += " ";
280         arguments += command->GetArgumentName(i);
281     }
282     fprintf(stderr, "  %s %s %s\n", executable.c_str(), clusterName.c_str(), arguments.c_str());
283 }