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 17 namespace Hdc { 18 namespace TranslateCommand { Usage()19 string Usage() 20 { 21 string ret; 22 23 ret = "\n OpenHarmony device connector(HDC) ...\n\n" 24 "---------------------------------global commands:----------------------------------\n" 25 " -h/help - Print hdc help\n" 26 " -v/version - Print hdc version\n" 27 " -l 0-5 - Set runtime loglevel\n" 28 " -t connectkey - Use device with given connect key\n" 29 "\n" 30 "---------------------------------component commands:-------------------------------\n" 31 "session commands(on server):\n" 32 " discover - Discover devices listening on TCP via LAN broadcast\n" 33 " list targets [-v] - List all devices status, -v for detail\n" 34 " tconn key - Connect device via key, TCP use ip:port\n" 35 " example:192.168.0.100:10178/192.168.0.100\n" 36 " USB connect automatic, TCP need to connect manually\n" 37 #ifdef HDC_SUPPORT_UART 38 "\n" 39 " UART connect need connect manually.\n" 40 " Baud Rate can be specified with commas.\n" 41 " key format: <Port Name>[,Baud Rate]\n" 42 " example: tconn COM5,921600\n" 43 " Default Baud Rate is 921600.\n" 44 "\n" 45 #endif 46 " start [-r] - Start server. If with '-r', will be restart server\n" 47 " kill [-r] - Kill server. If with '-r', will be restart server\n" 48 " -s [ip:]port - Set hdc server listen config\n" 49 "\n" 50 "service commands(on daemon):\n" 51 " target mount - Set /system /vendor partition read-write\n" 52 " target boot [-bootloader|-recovery] - Reboot the device or boot into bootloader\\recovery.\n" 53 " smode [-r] - Restart daemon with root permissions, '-r' to cancel root\n" 54 " permissions\n" 55 " tmode usb - Reboot the device, listening on USB\n" 56 " tmode port [port] - Reboot the device, listening on TCP port\n" 57 "\n" 58 "---------------------------------task commands:-------------------------------------\n" 59 "file commands:\n" 60 " file send [option] local remote - Send file to device\n" 61 " file recv [option] remote local - Recv file from device\n" 62 " option is -a|-s|-z\n" 63 " -a: hold target file timestamp\n" 64 " -sync: just update newer file\n" 65 " -z: compress transfer\n" 66 "\n" 67 "forward commands:\n" 68 " fport localnode remotenode - Forward local traffic to remote device\n" 69 " rport remotenode localnode - Reserve remote traffic to local host\n" 70 " node config name format 'schema:content'\n" 71 " examples are below:\n" 72 " tcp:<port>\n" 73 " localfilesystem:<unix domain socket name>\n" 74 " localreserved:<unix domain socket name>\n" 75 " localabstract:<unix domain socket name>\n" 76 " dev:<device name>\n" 77 " jdwp:<pid> (remote only)\n" 78 " fport ls - Dispaly forward/reverse tasks\n" 79 " fport rm taskstr - Remove forward/reverse task by taskstring\n" 80 "\n" 81 "app commands:\n" 82 " install [-rdg] src - Send package(s) to device and install them\n" 83 " src examples: single or multiple packages and directories\n" 84 " (.hap)\n" 85 " -r: replace existing application\n" 86 " -d: allow version code downgrade\n" 87 " -g: grant all the permissions\n" 88 " uninstall [-k] package - Remove application package from device\n" 89 " -k: keep the data and cache directories\n" 90 "\n" 91 "debug commands:\n" 92 " hilog [-v] - Show device log, -v for detail\n" 93 " shell [COMMAND...] - Run shell command (interactive shell if no command given)\n" 94 " bugreport [PATH] - Return all information from the device, path will be save " 95 "localpath\n" 96 " jpid - List pids of processes hosting a JDWP transport\n" 97 " sideload [PATH] - Sideload the given full OTA package\n" 98 "\n" 99 "security commands:\n" 100 " keygen FILE - Generate public/private key; key stored in FILE and FILE.pub\n"; 101 return ret; 102 } 103 TargetConnect(FormatCommand * outCmd)104 string TargetConnect(FormatCommand *outCmd) 105 { 106 string stringError; 107 if (Base::StringEndsWith(outCmd->parameters, " -remove")) { 108 outCmd->parameters = outCmd->parameters.substr(0, outCmd->parameters.size() - 8); 109 outCmd->cmdFlag = CMD_KERNEL_TARGET_DISCONNECT; 110 } else { 111 outCmd->cmdFlag = CMD_KERNEL_TARGET_CONNECT; 112 if (outCmd->parameters.size() > 22) { // 22: tcp max=21,USB max=8bytes 113 stringError = "Error connect key's size"; 114 outCmd->bJumpDo = true; 115 } 116 } 117 if (outCmd->parameters.find(":") != std::string::npos) { 118 // tcp mode 119 string ip = outCmd->parameters.substr(0, outCmd->parameters.find(":")); 120 string sport = outCmd->parameters.substr(outCmd->parameters.find(":") + 1); 121 if (sport.empty()) { 122 stringError = "Port incorrect"; 123 outCmd->bJumpDo = true; 124 return stringError; 125 } 126 int port = std::stoi(sport); 127 sockaddr_in addr; 128 if ((port <= 0 || port > MAX_IP_PORT) || uv_ip4_addr(ip.c_str(), port, &addr) < 0) { 129 stringError = "IP:Port incorrect"; 130 outCmd->bJumpDo = true; 131 } 132 } 133 return stringError; 134 } 135 ForwardPort(const char * input,FormatCommand * outCmd)136 string ForwardPort(const char *input, FormatCommand *outCmd) 137 { 138 string stringError; 139 const char *pExtra = input + 6; // CMDSTR_FORWARD_FPORT CMDSTR_FORWARD_RPORT + " " size 140 if (!strcmp(pExtra, "ls")) { 141 outCmd->cmdFlag = CMD_FORWARD_LIST; 142 } else if (!strncmp(pExtra, "rm", 2)) { // 2: "rm" size 143 outCmd->cmdFlag = CMD_FORWARD_REMOVE; 144 if (strcmp(pExtra, "rm")) { 145 outCmd->parameters = input + 9; 146 } 147 } else { 148 const char *p = input + 6; 149 // clang-format off 150 if (strncmp(p, "tcp:", 4) && strncmp(p, "localabstract:", 14) && strncmp(p, "localreserved:", 14) && 151 strncmp(p, "localfilesystem:", 16) && strncmp(p, "dev:", 4) && strncmp(p, "jdwp:", 5)) { 152 stringError = "Incorrect forward command"; 153 outCmd->bJumpDo = true; 154 } 155 // clang-format on 156 outCmd->cmdFlag = CMD_FORWARD_INIT; 157 outCmd->parameters = input; 158 } 159 return stringError; 160 } 161 RunMode(const char * input,FormatCommand * outCmd)162 string RunMode(const char *input, FormatCommand *outCmd) 163 { 164 string stringError; 165 outCmd->cmdFlag = CMD_UNITY_RUNMODE; 166 outCmd->parameters = input + CMDSTR_TARGET_MODE.size() + 1; // with ' ' 167 if (!strncmp(outCmd->parameters.c_str(), "port", 4) 168 && !strcmp(outCmd->parameters.c_str(), CMDSTR_TMODE_USB.c_str())) { 169 stringError = "Error tmode command"; 170 outCmd->bJumpDo = true; 171 } else if (!strncmp(outCmd->parameters.c_str(), "port ", 5)) { 172 int port = atoi(input + strlen("tmode port ")); 173 if (port > MAX_IP_PORT || port <= 0) { 174 stringError = "Incorrect port range"; 175 outCmd->bJumpDo = true; 176 } 177 } 178 return stringError; 179 } 180 TargetReboot(const char * input,FormatCommand * outCmd)181 string TargetReboot(const char *input, FormatCommand *outCmd) 182 { 183 string stringError; 184 outCmd->cmdFlag = CMD_UNITY_REBOOT; 185 if (strcmp(input, CMDSTR_TARGET_REBOOT.c_str())) { 186 outCmd->parameters = input + 12; 187 if (outCmd->parameters != "-bootloader" && outCmd->parameters != "-recovery") { 188 stringError = "Error reboot paramenter"; 189 outCmd->bJumpDo = true; 190 } else { 191 outCmd->parameters.erase(outCmd->parameters.begin()); 192 } 193 } 194 return stringError; 195 } 196 197 // command input 198 // client side:Enter string data formatting conversion to module see internal processing command String2FormatCommand(const char * inputRaw,int sizeInputRaw,FormatCommand * outCmd)199 string String2FormatCommand(const char *inputRaw, int sizeInputRaw, FormatCommand *outCmd) 200 { 201 string stringError; 202 string input = string(inputRaw, sizeInputRaw); 203 if (!strcmp(input.c_str(), CMDSTR_SOFTWARE_HELP.c_str())) { 204 outCmd->cmdFlag = CMD_KERNEL_HELP; 205 stringError = Usage(); 206 outCmd->bJumpDo = true; 207 } else if (!strcmp(input.c_str(), CMDSTR_SOFTWARE_VERSION.c_str())) { 208 outCmd->cmdFlag = CMD_KERNEL_HELP; 209 stringError = Base::GetVersion(); 210 outCmd->bJumpDo = true; 211 } else if (!strcmp(input.c_str(), CMDSTR_TARGET_DISCOVER.c_str())) { 212 outCmd->cmdFlag = CMD_KERNEL_TARGET_DISCOVER; 213 } else if (!strncmp(input.c_str(), CMDSTR_LIST_TARGETS.c_str(), CMDSTR_LIST_TARGETS.size())) { 214 outCmd->cmdFlag = CMD_KERNEL_TARGET_LIST; 215 if (strstr(input.c_str(), " -v")) { 216 outCmd->parameters = "v"; 217 } 218 } else if (!strcmp(input.c_str(), CMDSTR_CONNECT_ANY.c_str())) { 219 outCmd->cmdFlag = CMD_KERNEL_TARGET_ANY; 220 } else if (!strncmp(input.c_str(), CMDSTR_CONNECT_TARGET.c_str(), CMDSTR_CONNECT_TARGET.size())) { 221 outCmd->parameters = input.c_str() + CMDSTR_CONNECT_TARGET.size() + 1; // with ' ' 222 stringError = TargetConnect(outCmd); 223 } else if (!strncmp(input.c_str(), (CMDSTR_SHELL + " ").c_str(), CMDSTR_SHELL.size() + 1)) { 224 outCmd->cmdFlag = CMD_UNITY_EXECUTE; 225 outCmd->parameters = input.c_str() + CMDSTR_SHELL.size() + 1; 226 } else if (!strcmp(input.c_str(), CMDSTR_SHELL.c_str())) { 227 outCmd->cmdFlag = CMD_SHELL_INIT; 228 } else if (!strncmp(input.c_str(), CMDSTR_FILE_SEND.c_str(), CMDSTR_FILE_SEND.size()) 229 || !strncmp(input.c_str(), CMDSTR_FILE_RECV.c_str(), CMDSTR_FILE_RECV.size())) { 230 outCmd->cmdFlag = CMD_FILE_INIT; 231 outCmd->parameters = input.c_str() + 5; // 5: CMDSTR_FORWARD_FPORT CMDSTR_FORWARD_RPORT size 232 } else if (!strncmp(input.c_str(), string(CMDSTR_FORWARD_FPORT + " ").c_str(), CMDSTR_FORWARD_FPORT.size() + 1) 233 || !strncmp(input.c_str(), string(CMDSTR_FORWARD_RPORT + " ").c_str(), 234 CMDSTR_FORWARD_RPORT.size() + 1)) { 235 stringError = ForwardPort(input.c_str(), outCmd); 236 } else if (!strcmp(input.c_str(), CMDSTR_KILL_SERVER.c_str())) { 237 outCmd->cmdFlag = CMD_KERNEL_SERVER_KILL; 238 } else if (!strcmp(input.c_str(), CMDSTR_KILL_DAEMON.c_str())) { 239 outCmd->cmdFlag = CMD_UNITY_TERMINATE; 240 outCmd->parameters = "0"; 241 } else if (!strncmp(input.c_str(), CMDSTR_APP_INSTALL.c_str(), CMDSTR_APP_INSTALL.size())) { 242 outCmd->cmdFlag = CMD_APP_INIT; 243 outCmd->parameters = input; 244 } else if (!strncmp(input.c_str(), CMDSTR_APP_UNINSTALL.c_str(), CMDSTR_APP_UNINSTALL.size())) { 245 outCmd->cmdFlag = CMD_APP_UNINSTALL; 246 outCmd->parameters = input; 247 if (outCmd->parameters.size() > 512 || outCmd->parameters.size() < 4) { 248 stringError = "Package's path incorrect"; 249 outCmd->bJumpDo = true; 250 } 251 } else if (!strcmp(input.c_str(), CMDSTR_TARGET_MOUNT.c_str())) { 252 outCmd->cmdFlag = CMD_UNITY_REMOUNT; 253 } else if (!strcmp(input.c_str(), CMDSTR_LIST_JDWP.c_str())) { 254 outCmd->cmdFlag = CMD_JDWP_LIST; 255 } else if (!strcmp(input.c_str(), CMDSTR_TRACK_JDWP.c_str())) { 256 outCmd->cmdFlag = CMD_JDWP_TRACK; 257 } else if (!strncmp(input.c_str(), CMDSTR_TARGET_REBOOT.c_str(), CMDSTR_TARGET_REBOOT.size())) { 258 stringError = TargetReboot(input.c_str(), outCmd); 259 } else if (!strncmp(input.c_str(), CMDSTR_TARGET_MODE.c_str(), CMDSTR_TARGET_MODE.size())) { 260 stringError = RunMode(input.c_str(), outCmd); 261 } else if (!strncmp(input.c_str(), CMDSTR_HILOG.c_str(), CMDSTR_HILOG.size())) { 262 outCmd->cmdFlag = CMD_UNITY_HILOG; 263 if (strstr(input.c_str(), " -v")) { 264 outCmd->parameters = "v"; 265 } 266 } else if (!strncmp(input.c_str(), CMDSTR_STARTUP_MODE.c_str(), CMDSTR_STARTUP_MODE.size())) { 267 outCmd->cmdFlag = CMD_UNITY_ROOTRUN; 268 if (strstr(input.c_str(), " -r")) { 269 outCmd->parameters = "r"; 270 } 271 } else if (!strncmp(input.c_str(), CMDSTR_APP_SIDELOAD.c_str(), CMDSTR_APP_SIDELOAD.size())) { 272 if (strlen(input.c_str()) == CMDSTR_APP_SIDELOAD.size()) { 273 stringError = "Incorrect command, please with local path"; 274 outCmd->bJumpDo = true; 275 } 276 outCmd->cmdFlag = CMD_APP_SIDELOAD; 277 outCmd->parameters = input; 278 } else if (!strncmp(input.c_str(), CMDSTR_BUGREPORT.c_str(), CMDSTR_BUGREPORT.size())) { 279 outCmd->cmdFlag = CMD_UNITY_BUGREPORT_INIT; 280 outCmd->parameters = input; 281 if (outCmd->parameters.size() == CMDSTR_BUGREPORT.size()) { 282 outCmd->parameters += " "; 283 } 284 } 285 // Inner command, protocol uses only 286 else if (!strncmp(input.c_str(), CMDSTR_INNER_ENABLE_KEEPALIVE.c_str(), CMDSTR_INNER_ENABLE_KEEPALIVE.size())) { 287 outCmd->cmdFlag = CMD_KERNEL_ENABLE_KEEPALIVE; 288 } else { 289 stringError = "Unknown command..."; 290 outCmd->bJumpDo = true; 291 } 292 #ifdef HDC_DEBUG 293 WRITE_LOG(LOG_DEBUG, "String2FormatCommand cmdFlag:%d", outCmd->cmdFlag); 294 #endif 295 // nl 296 if (stringError.size()) { 297 stringError += "\n"; 298 } 299 return stringError; 300 }; 301 } 302 } // namespace Hdc 303