xref: /developtools/hdc/src/host/translate.cpp (revision cc290419)
1/*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include "translate.h"
16#include "host_updater.h"
17
18namespace Hdc {
19namespace TranslateCommand {
20    string Usage()
21    {
22        string ret = "";
23        ret = "\n                         OpenHarmony device connector(HDC) ...\n\n"
24              "---------------------------------global commands:----------------------------------\n"
25              " -h/help [verbose]                     - Print hdc help, 'verbose' for more other cmds\n"
26              " -v/version                            - Print hdc version\n"
27              " -t connectkey                         - Use device with given connect key\n"
28              "\n"
29              "---------------------------------component commands:-------------------------------\n"
30              "session commands(on server):\n"
31              " list targets [-v]                     - List all devices status, -v for detail\n"
32              " start [-r]                            - Start server. If with '-r', will be restart server\n"
33              " kill [-r]                             - Kill server. If with '-r', will be restart server\n"
34              "\n"
35              "service commands(on daemon):\n"
36              " target mount                          - Set /system /vendor partition read-write\n"
37              " wait                                  - Wait for the device to become available\n"
38              " target boot [-bootloader|-recovery]   - Reboot the device or boot into bootloader\\recovery.\n"
39              " target boot [MODE]                    - Reboot the into MODE.\n"
40              " smode [-r]                            - Restart daemon with root permissions, '-r' to cancel root\n"
41              "                                         permissions\n"
42              " tmode usb                             - Reboot the device, listening on USB\n"
43              " tmode port [port]                     - Reboot the device, listening on TCP port\n"
44              "\n"
45              "---------------------------------task commands:-------------------------------------\n"
46              "file commands:\n"
47              " file send [option] local remote       - Send file to device\n"
48              " file recv [option] remote local       - Recv file from device\n"
49              "                                         option is -a|-s|-z\n"
50              "                                         -a: hold target file timestamp\n"
51              "                                         -sync: just update newer file\n"
52              "                                         -z: compress transfer\n"
53              "                                         -m: mode sync\n"
54              "\n"
55              "forward commands:\n"
56              " fport localnode remotenode            - Forward local traffic to remote device\n"
57              " rport remotenode localnode            - Reserve remote traffic to local host\n"
58              "                                         node config name format 'schema:content'\n"
59              "                                         examples are below:\n"
60              "                                         tcp:<port>\n"
61              "                                         localfilesystem:<unix domain socket name>\n"
62              "                                         localreserved:<unix domain socket name>\n"
63              "                                         localabstract:<unix domain socket name>\n"
64              "                                         dev:<device name>\n"
65              "                                         jdwp:<pid> (remote only)\n"
66              " fport ls                              - Display forward/reverse tasks\n"
67              " fport rm taskstr                      - Remove forward/reverse task by taskstring\n"
68              "\n"
69              "app commands:\n"
70              " install [-r|-s] src                   - Send package(s) to device and install them\n"
71              "                                         src examples: single or multiple packages and directories\n"
72              "                                         (.hap .hsp)\n"
73              "                                         -r: replace existing application\n"
74              "                                         -s: install shared bundle for multi-apps\n"
75              " uninstall [-k] [-s] package           - Remove application package from device\n"
76              "                                         -k: keep the data and cache directories\n"
77              "                                         -s: remove shared bundle\n"
78              "\n"
79              "debug commands:\n"
80              " hilog [-h]                            - Show device log, -h for detail\n"
81              " shell [COMMAND...]                    - Run shell command (interactive shell if no command given)\n"
82              " bugreport [FILE]                      - Return all information from the device, stored in file if "
83              "FILE is specified\n"
84              " jpid                                  - List PIDs of processes hosting a JDWP transport\n"
85              " track-jpid [-a|-p]                    - Track PIDs of debug processes hosting a JDWP transport\n"
86              "                                         -a: include debug and release processes\n"
87              "                                         -p: don't display debug and release tags\n"
88              "\n"
89              "security commands:\n"
90              " keygen FILE                           - Generate public/private key; key stored in FILE and FILE.pub\n"
91              "\n";
92        return ret;
93    }
94
95    string Verbose()
96    {
97        string ret = "\n                         OpenHarmony device connector(HDC) ...\n\n"
98            "---------------------------------global commands:----------------------------------\n"
99            " -h/help [verbose]                     - Print hdc help, 'verbose' for more other cmds\n"
100            " -v/version                            - Print hdc version\n"
101            " -l[0-5]                               - Set runtime loglevel\n"
102            " -t connectkey                         - Use device with given connect key\n"
103            " checkserver                           - check client-server version\n"
104            " checkdevice                           - check server-daemon version(only uart)\n"
105            "\n"
106            "---------------------------------component commands:-------------------------------\n"
107            "session commands(on server):\n"
108            " discover                              - Discover devices listening on TCP via LAN broadcast\n"
109            " list targets [-v]                     - List all devices status, -v for detail\n"
110            " tconn key                             - Connect device via key, TCP use ip:port\n"
111            "                                         example:192.168.0.100:10178/192.168.0.100\n"
112            "                                         USB connect automatic, TCP need to connect manually\n"
113#ifdef HDC_SUPPORT_UART
114            "\n"
115            "                                         UART connect need connect manually.\n"
116            "                                         Baud Rate can be specified with commas.\n"
117            "                                         key format: <Port Name>[,Baud Rate]\n"
118            "                                         example: tconn COM5,921600\n"
119            "                                         Default Baud Rate is 921600.\n"
120            "\n"
121#endif
122            " start [-r]                            - Start server. If with '-r', will be restart server\n"
123            " kill [-r]                             - Kill server. If with '-r', will be restart server\n"
124            " -s [ip:]port                          - Set hdc server listen config\n"
125            "\n"
126            "service commands(on daemon):\n"
127            " target mount                          - Set /system /vendor partition read-write\n"
128            " target boot [-bootloader|-recovery]   - Reboot the device or boot into bootloader\\recovery.\n"
129            " target boot [MODE]                    - Reboot the into MODE.\n"
130            " smode [-r]                            - Restart daemon with root permissions, '-r' to cancel root\n"
131            "                                         permissions\n"
132            " tmode usb                             - Reboot the device, listening on USB\n"
133            " tmode port [port]                     - Reboot the device, listening on TCP port\n"
134            "\n"
135            "---------------------------------task commands:-------------------------------------\n"
136            "file commands:\n"
137            " file send [option] local remote       - Send file to device\n"
138            " file recv [option] remote local       - Recv file from device\n"
139            "                                         option is -a|-s|-z\n"
140            "                                         -a: hold target file timestamp\n"
141            "                                         -sync: just update newer file\n"
142            "                                         -z: compress transfer\n"
143            "                                         -m: mode sync\n"
144            "\n"
145            "forward commands:\n"
146            " fport localnode remotenode            - Forward local traffic to remote device\n"
147            " rport remotenode localnode            - Reserve remote traffic to local host\n"
148            "                                         node config name format 'schema:content'\n"
149            "                                         examples are below:\n"
150            "                                         tcp:<port>\n"
151            "                                         localfilesystem:<unix domain socket name>\n"
152            "                                         localreserved:<unix domain socket name>\n"
153            "                                         localabstract:<unix domain socket name>\n"
154            "                                         dev:<device name>\n"
155            "                                         jdwp:<pid> (remote only)\n"
156            " fport ls                              - Display forward/reverse tasks\n"
157            " fport rm taskstr                      - Remove forward/reverse task by taskstring\n"
158            "\n"
159            "app commands:\n"
160            " install [-r|-s] src                   - Send package(s) to device and install them\n"
161            "                                         src examples: single or multiple packages and directories\n"
162            "                                         (.hap .hsp)\n"
163            "                                         -r: replace existing application\n"
164            "                                         -s: install shared bundle for multi-apps\n"
165            " uninstall [-k] [-s] package           - Remove application package from device\n"
166            "                                         -k: keep the data and cache directories\n"
167            "                                         -s: remove shared bundle\n"
168            "\n"
169            "debug commands:\n"
170            " hilog [-h]                            - Show device log, -h for detail\n"
171            " shell [COMMAND...]                    - Run shell command (interactive shell if no command given)\n"
172            " bugreport [FILE]                      - Return all information from the device, stored in file if FILE "
173            "is specified\n"
174            " jpid                                  - List PIDs of processes hosting a JDWP transport\n"
175            " sideload [PATH]                       - Sideload the given full OTA package\n"
176            "\n"
177            "security commands:\n"
178            " keygen FILE                           - Generate public/private key; key stored in FILE and FILE.pub\n"
179            "\n"
180            "---------------------------------flash commands:------------------------------------\n"
181            "flash commands:\n"
182            " update packagename                    - Update system by package\n"
183            " flash [-f] partition imagename        - Flash partition by image\n"
184            " erase [-f] partition                  - Erase partition\n"
185            " format [-f] partition                 - Format partition\n"
186            "---------------------------------external commands:------------------------------------\n"
187            "extconn key                             - Connect external device via key, TCP use ip:port(remian)\n"
188            "-S [ip:]port                            - Set hdc external server listen config\n"
189            "\n";
190        return ret;
191    }
192
193    string TargetConnect(FormatCommand *outCmd)
194    {
195        string stringError;
196        if (Base::StringEndsWith(outCmd->parameters, " -remove")) {
197            outCmd->parameters = outCmd->parameters.substr(0, outCmd->parameters.size() - CMD_REMOTE_SIZE);
198            outCmd->cmdFlag = CMD_KERNEL_TARGET_DISCONNECT;
199        } else {
200            outCmd->cmdFlag = CMD_KERNEL_TARGET_CONNECT;
201            constexpr int maxKeyLength = 50; // 50: tcp max=21,USB max=8bytes, serial device name maybe long
202            if (outCmd->parameters.size() > maxKeyLength) {
203                stringError = "Error connect key's size";
204                outCmd->bJumpDo = true;
205            }
206        }
207        size_t pos = outCmd->parameters.find(":");
208        if (pos != std::string::npos) {
209            // tcp mode
210            string ip = outCmd->parameters.substr(0, pos);
211            if (!Base::IsValidIpv4(ip)) {
212                stringError = "[E001104]:IP address incorrect";
213                outCmd->bJumpDo = true;
214                return stringError;
215            }
216            string sport = outCmd->parameters.substr(pos + 1);
217            if (sport.empty() || !Base::IsDigitString(sport)) {
218                stringError = "Port incorrect";
219                outCmd->bJumpDo = true;
220                return stringError;
221            }
222            if (ip == "localhost") {
223                ip = "127.0.0.1";
224                outCmd->parameters.replace(0, pos, ip);
225            }
226            int port = std::stoi(sport);
227            sockaddr_in addr;
228            if ((port <= 0 || port > MAX_IP_PORT) || uv_ip4_addr(ip.c_str(), port, &addr) < 0) {
229                stringError = "IP:Port incorrect";
230                outCmd->bJumpDo = true;
231            }
232        }
233        return stringError;
234    }
235
236    string ForwardPort(const char *input, FormatCommand *outCmd)
237    {
238        string stringError;
239        const char *pExtra = input + 6;  // CMDSTR_FORWARD_FPORT CMDSTR_FORWARD_RPORT + " " size
240        if (!strncmp(input, CMDSTR_FORWARD_FPORT.c_str(), CMDSTR_FORWARD_FPORT.size()) && !strcmp(pExtra, "ls")) {
241            outCmd->cmdFlag = CMD_FORWARD_LIST;
242        } else if (!strncmp(input, CMDSTR_FORWARD_FPORT.c_str(), CMDSTR_FORWARD_FPORT.size()) &&
243            !strncmp(pExtra, "rm", 2)) { // 2: "rm" size
244            outCmd->cmdFlag = CMD_FORWARD_REMOVE;
245            if (strcmp(pExtra, "rm")) {
246                outCmd->parameters = input + FORWORD_PORT_RM_BUF_SIZE;
247            }
248        } else {
249            const char *p = input + FORWORD_PORT_OTHER_BUF_SIZE;
250            // clang-format off
251            if (strncmp(p, "tcp:", 4) && // 4: "tcp:" size
252                strncmp(p, "localabstract:", 14) && // 14: "localabstract:" size
253                strncmp(p, "localreserved:", 14) && // 14: "localreserved:" size
254                strncmp(p, "localfilesystem:", 16) && // 16: "localfilesystem:" size
255                strncmp(p, "dev:", 4) && // 4: "dev:" size
256                strncmp(p, "jdwp:", 5) && // 5: "jdwp:" size
257                strncmp(p, "ark:", 4)) { // 4: "ark:" size
258                stringError = "Incorrect forward command";
259                outCmd->bJumpDo = true;
260            }
261            // clang-format on
262            outCmd->cmdFlag = CMD_FORWARD_INIT;
263            outCmd->parameters = input;
264        }
265        return stringError;
266    }
267
268    string RunMode(const char *input, FormatCommand *outCmd)
269    {
270        string stringError;
271        outCmd->cmdFlag = CMD_UNITY_RUNMODE;
272        outCmd->parameters = input + CMDSTR_TARGET_MODE.size() + 1;  // with  ' '
273        int portLength = 4;
274        int portSpaceLength = 5;
275        if (!strncmp(outCmd->parameters.c_str(), "port", portLength) &&
276            !strcmp(outCmd->parameters.c_str(), CMDSTR_TMODE_USB.c_str())) {
277            stringError = "Error tmode command";
278            outCmd->bJumpDo = true;
279        } else if (!strncmp(outCmd->parameters.c_str(), "port ", portSpaceLength)) {
280            const char *tmp = input + strlen("tmode port ");
281            // command is tmode port close
282            if (strcmp(tmp, "close") == 0) {
283                return stringError;
284            }
285            int port = atoi(tmp);
286            if (port > MAX_IP_PORT || port <= 0) {
287                stringError = "Incorrect port range";
288                outCmd->bJumpDo = true;
289            }
290        }
291        return stringError;
292    }
293
294    void TargetReboot(const char *input, FormatCommand *outCmd)
295    {
296        outCmd->cmdFlag = CMD_UNITY_REBOOT;
297        if (strcmp(input, CMDSTR_TARGET_REBOOT.c_str())) {
298            outCmd->parameters = input + CMDSTR_TARGET_REBOOT.size() + 1;  // with  ' '
299            if (outCmd->parameters == "-bootloader" || outCmd->parameters == "-recovery" ||
300                outCmd->parameters == "-flashd") {
301                outCmd->parameters.erase(outCmd->parameters.begin());
302            }
303        }
304    }
305
306    // command input
307    // client side:Enter string data formatting conversion to module see internal processing command
308    string String2FormatCommand(const char *inputRaw, int sizeInputRaw, FormatCommand *outCmd)
309    {
310        string stringError;
311        string input = string(inputRaw, sizeInputRaw);
312        if (!strncmp(input.c_str(), CMDSTR_SOFTWARE_HELP.c_str(), CMDSTR_SOFTWARE_HELP.size())) {
313            outCmd->cmdFlag = CMD_KERNEL_HELP;
314            outCmd->bJumpDo = true;
315            if (strstr(input.c_str(), " verbose")) {
316                stringError = Verbose();
317            } else {
318                stringError = Usage();
319            }
320        } else if (!strcmp(input.c_str(), CMDSTR_SOFTWARE_VERSION.c_str())) {
321            outCmd->cmdFlag = CMD_KERNEL_HELP;
322            stringError = Base::GetVersion();
323            outCmd->bJumpDo = true;
324        } else if (!strcmp(input.c_str(), CMDSTR_TARGET_DISCOVER.c_str())) {
325            outCmd->cmdFlag = CMD_KERNEL_TARGET_DISCOVER;
326        } else if (!strncmp(input.c_str(), CMDSTR_LIST_TARGETS.c_str(), CMDSTR_LIST_TARGETS.size())) {
327            outCmd->cmdFlag = CMD_KERNEL_TARGET_LIST;
328            if (strstr(input.c_str(), " -v")) {
329                outCmd->parameters = "v";
330            }
331        } else if (!strncmp(input.c_str(), CMDSTR_CHECK_SERVER.c_str(), CMDSTR_CHECK_SERVER.size())) {
332            outCmd->cmdFlag = CMD_CHECK_SERVER;
333        } else if (!strncmp(input.c_str(), CMDSTR_CHECK_DEVICE.c_str(), CMDSTR_CHECK_DEVICE.size())) {
334            outCmd->parameters = input.c_str() + CMDSTR_CHECK_DEVICE.size() + 1;  // with ' '
335            outCmd->cmdFlag = CMD_CHECK_DEVICE;
336        } else if (!strncmp(input.c_str(), CMDSTR_WAIT_FOR.c_str(), CMDSTR_WAIT_FOR.size())) {
337            outCmd->cmdFlag = CMD_WAIT_FOR;
338        } else if (!strcmp(input.c_str(), CMDSTR_CONNECT_ANY.c_str())) {
339            outCmd->cmdFlag = CMD_KERNEL_TARGET_ANY;
340        } else if (!strncmp(input.c_str(), CMDSTR_CONNECT_TARGET.c_str(), CMDSTR_CONNECT_TARGET.size())) {
341            outCmd->parameters = input.c_str() + CMDSTR_CONNECT_TARGET.size() + 1;  // with ' '
342            stringError = TargetConnect(outCmd);
343        } else if (!strncmp(input.c_str(), (CMDSTR_SHELL + " ").c_str(), CMDSTR_SHELL.size() + 1)) {
344            outCmd->cmdFlag = CMD_UNITY_EXECUTE;
345            outCmd->parameters = input.c_str() + CMDSTR_SHELL.size() + 1;
346        } else if (!strcmp(input.c_str(), CMDSTR_SHELL.c_str())) {
347            outCmd->cmdFlag = CMD_SHELL_INIT;
348        } else if (!strncmp(input.c_str(), CMDSTR_FILE_SEND.c_str(), CMDSTR_FILE_SEND.size()) ||
349                   !strncmp(input.c_str(), CMDSTR_FILE_RECV.c_str(), CMDSTR_FILE_RECV.size())) {
350            outCmd->cmdFlag = CMD_FILE_INIT;
351            outCmd->parameters = input.c_str() + strlen("file ");
352        } else if (!strncmp(input.c_str(), string(CMDSTR_FORWARD_FPORT + " ").c_str(), CMDSTR_FORWARD_FPORT.size() + 1)
353                   || !strncmp(input.c_str(), string(CMDSTR_FORWARD_RPORT + " ").c_str(),
354                               CMDSTR_FORWARD_RPORT.size() + 1)) {
355            stringError = ForwardPort(input.c_str(), outCmd);
356        } else if (!strncmp(input.c_str(), CMDSTR_APP_INSTALL.c_str(), CMDSTR_APP_INSTALL.size())) {
357            outCmd->cmdFlag = CMD_APP_INIT;
358            outCmd->parameters = input;
359        } else if (!strncmp(input.c_str(), CMDSTR_APP_UNINSTALL.c_str(), CMDSTR_APP_UNINSTALL.size())) {
360            outCmd->cmdFlag = CMD_APP_UNINSTALL;
361            outCmd->parameters = input;
362            if (outCmd->parameters.size() > MAX_APP_PARAM_SIZE || outCmd->parameters.size() < MIN_APP_PARAM_SIZE) {
363                stringError = "Package's path incorrect";
364                outCmd->bJumpDo = true;
365            }
366        } else if (!strcmp(input.c_str(), CMDSTR_TARGET_MOUNT.c_str())) {
367            outCmd->cmdFlag = CMD_UNITY_REMOUNT;
368        } else if (!strcmp(input.c_str(), CMDSTR_LIST_JDWP.c_str())) {
369            outCmd->cmdFlag = CMD_JDWP_LIST;
370        } else if (!strncmp(input.c_str(), CMDSTR_TRACK_JDWP.c_str(), CMDSTR_TRACK_JDWP.size())) {
371            outCmd->cmdFlag = CMD_JDWP_TRACK;
372            if (strstr(input.c_str(), " -p")) {
373                outCmd->parameters = "p";
374            } else if (strstr(input.c_str(), " -a")) {
375                outCmd->parameters = "a";
376            }
377        } else if (!strncmp(input.c_str(), CMDSTR_TARGET_REBOOT.c_str(), CMDSTR_TARGET_REBOOT.size())) {
378            TargetReboot(input.c_str(), outCmd);
379        } else if (!strncmp(input.c_str(), CMDSTR_TARGET_MODE.c_str(), CMDSTR_TARGET_MODE.size())) {
380            stringError = RunMode(input.c_str(), outCmd);
381        } else if (!strncmp(input.c_str(), CMDSTR_HILOG.c_str(), CMDSTR_HILOG.size())) {
382            outCmd->cmdFlag = CMD_UNITY_HILOG;
383            if (strstr(input.c_str(), " -h")) {
384                outCmd->parameters = "h";
385            }
386        } else if (!strncmp(input.c_str(), CMDSTR_STARTUP_MODE.c_str(), CMDSTR_STARTUP_MODE.size())) {
387            outCmd->cmdFlag = CMD_UNITY_ROOTRUN;
388            if (strstr(input.c_str(), " -r")) {
389                outCmd->parameters = "r";
390            }
391        } else if (!strncmp(input.c_str(), CMDSTR_APP_SIDELOAD.c_str(), CMDSTR_APP_SIDELOAD.size())) {
392            if (strlen(input.c_str()) == CMDSTR_APP_SIDELOAD.size()) {
393                stringError = "Incorrect command, please with local path";
394                outCmd->bJumpDo = true;
395            }
396            outCmd->cmdFlag = CMD_APP_SIDELOAD;
397            outCmd->parameters = input;
398        } else if (!strncmp(input.c_str(), CMDSTR_BUGREPORT.c_str(), CMDSTR_BUGREPORT.size())) {
399            outCmd->cmdFlag = CMD_UNITY_BUGREPORT_INIT;
400            outCmd->parameters = input;
401            if (outCmd->parameters.size() == CMDSTR_BUGREPORT.size() + 1) { // 1 is sizeInputRaw = input.size() + 1
402                outCmd->parameters = CMDSTR_BUGREPORT + " ";
403            }
404        }
405        // Inner command, protocol uses only
406        else if (!strncmp(input.c_str(), CMDSTR_INNER_ENABLE_KEEPALIVE.c_str(), CMDSTR_INNER_ENABLE_KEEPALIVE.size())) {
407            outCmd->cmdFlag = CMD_KERNEL_ENABLE_KEEPALIVE;
408        } else if (HostUpdater::CheckMatchUpdate(input, *outCmd)) {
409            outCmd->parameters = input;
410        } else {
411            stringError = "Unknown command...";
412            outCmd->bJumpDo = true;
413        }
414#ifdef HDC_DEBUG
415        WRITE_LOG(LOG_DEBUG, "String2FormatCommand cmdFlag:%d", outCmd->cmdFlag);
416#endif
417        // nl
418        if (stringError.size()) {
419            stringError += "\n";
420        }
421        return stringError;
422    };
423}
424}  // namespace Hdc
425