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