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 #ifndef DEFINE_PLUS_H 16 #define DEFINE_PLUS_H 17 18 #include <sstream> 19 #include <thread> 20 21 namespace Hdc { 22 // ############################# enum define ################################### 23 enum LogLevel { 24 LOG_OFF, 25 LOG_FATAL, 26 LOG_WARN, 27 LOG_INFO, // default 28 LOG_DEBUG, 29 LOG_ALL, 30 LOG_VERBOSE, 31 LOG_LAST = LOG_VERBOSE, // tail, not use 32 }; 33 #define WRITE_LOG(x, y...) Base::PrintLogEx(__FILE__, __LINE__, x, y) 34 35 enum MessageLevel { 36 MSG_FAIL, 37 MSG_INFO, 38 MSG_OK, 39 }; 40 41 enum ConnType { CONN_USB = 0, CONN_TCP, CONN_SERIAL, CONN_BT }; 42 43 #ifdef HDC_SUPPORT_UART 44 enum UartTimeConst { 45 UV_TIMEOUT = 10, 46 UV_REPEAT = 100, 47 TIMEOUTS_R_INTERALTIMEOUT = 1000, 48 TIMEOUTS_R_TOALTIMEOUTMULTIPLIER = 500, 49 TIMEOUTS_R_TIMEOUTCONSTANT = 5000 50 }; 51 enum UartSetSerialNBits { 52 UART_BIT1 = 7, 53 UART_BIT2 = 8 54 }; 55 enum UartSetSerialNSpeed { 56 UART_SPEED2400 = 2400, 57 UART_SPEED4800 = 4800, 58 UART_SPEED9600 = 9600, 59 UART_SPEED115200 = 115200, 60 UART_SPEED921600 = 921600, 61 UART_SPEED1500000 = 1500000 62 }; 63 enum UartSetSerialNStop { 64 UART_STOP1 = 1, 65 UART_STOP2 = 2 66 }; 67 #endif 68 enum ConnStatus { STATUS_UNKNOW = 0, STATUS_READY, STATUS_CONNECTED, STATUS_OFFLINE }; 69 70 enum OperateID { 71 OP_ADD, 72 OP_REMOVE, 73 OP_QUERY, 74 OP_QUERY_REF, // crossthread query, manually reduce ref 75 OP_GET_STRLIST, 76 OP_GET_STRLIST_FULL, 77 OP_GET_ANY, 78 OP_UPDATE, 79 OP_CLEAR, 80 OP_INIT, 81 OP_GET_ONLY, 82 OP_VOTE_RESET, 83 OP_WAIT_FOR_ANY 84 }; 85 86 enum RetErrCode { 87 RET_SUCCESS = 0, 88 ERR_GENERIC = -1, 89 ERR_NO_SUPPORT = -2, 90 ERR_BUF_SIZE = -10000, 91 ERR_BUF_ALLOC, 92 ERR_BUF_OVERFLOW, 93 ERR_BUF_CHECK, 94 ERR_BUF_RESET, 95 ERR_BUF_COPY, 96 ERR_CHECK_VERSION, 97 ERR_FILE_OPEN = -11000, 98 ERR_FILE_READ, 99 ERR_FILE_WRITE, 100 ERR_FILE_STAT, 101 ERR_FILE_PATH_CHECK, 102 ERR_PARM_FORMAT = -12000, 103 ERR_PARM_SIZE, 104 ERR_PARM_FAIL, 105 ERR_API_FAIL = -13000, 106 ERR_IO_FAIL = -14000, 107 ERR_IO_TIMEOUT, 108 ERR_IO_SOFT_RESET, 109 ERR_SESSION_NOFOUND = -15000, 110 ERR_SESSION_OFFLINE, 111 ERR_SESSION_DEAD, 112 ERR_HANDSHAKE_NOTMATCH = -16000, 113 ERR_HANDSHAKE_CONNECTKEY_FAILED, 114 ERR_HANDSHAKE_HANGUP_CHILD, 115 ERR_SOCKET_FAIL = -17000, 116 ERR_SOCKET_DUPLICATE, 117 ERR_MODULE_JDWP_FAILED = -18000, 118 ERR_UT_MODULE_NOTREADY = -19000, 119 ERR_UT_MODULE_WAITMAX, 120 ERR_THREAD_MUTEX_FAIL = -20000, 121 ERR_PROCESS_SUB_FAIL = -21000, 122 ERR_PRIVELEGE_NEED = -22000, 123 }; 124 125 // Flags shared by multiple modules 126 enum AsyncEvent { 127 ASYNC_STOP_MAINLOOP = 0, 128 ASYNC_FREE_SESSION, 129 ASYNC_FREE_CHANNEL, 130 }; 131 enum InnerCtrlCommand { 132 SP_START_SESSION = 0, 133 SP_STOP_SESSION, 134 SP_ATTACH_CHANNEL, 135 SP_DEATCH_CHANNEL, 136 SP_JDWP_NEWFD, 137 }; 138 139 enum HdcCommand { 140 // core commands types 141 CMD_KERNEL_HELP = 0, 142 CMD_KERNEL_HANDSHAKE, 143 CMD_KERNEL_CHANNEL_CLOSE, 144 CMD_KERNEL_SERVER_KILL, 145 CMD_KERNEL_TARGET_DISCOVER, 146 CMD_KERNEL_TARGET_LIST, 147 CMD_KERNEL_TARGET_ANY, 148 CMD_KERNEL_TARGET_CONNECT, 149 CMD_KERNEL_TARGET_DISCONNECT, 150 CMD_KERNEL_ECHO, 151 CMD_KERNEL_ECHO_RAW, 152 CMD_KERNEL_ENABLE_KEEPALIVE, 153 CMD_KERNEL_WAKEUP_SLAVETASK, 154 CMD_CHECK_SERVER, 155 CMD_CHECK_DEVICE, 156 CMD_WAIT_FOR, 157 // One-pass simple commands 158 CMD_UNITY_COMMAND_HEAD = 1000, // not use 159 CMD_UNITY_EXECUTE, 160 CMD_UNITY_REMOUNT, 161 CMD_UNITY_REBOOT, 162 CMD_UNITY_RUNMODE, 163 CMD_UNITY_HILOG, 164 CMD_UNITY_TERMINATE, 165 CMD_UNITY_ROOTRUN, 166 CMD_JDWP_LIST, 167 CMD_JDWP_TRACK, 168 CMD_UNITY_COMMAND_TAIL, // not use 169 // It will be separated from unity in the near future 170 CMD_UNITY_BUGREPORT_INIT, 171 CMD_UNITY_BUGREPORT_DATA, 172 // Shell commands types 173 CMD_SHELL_INIT = 2000, 174 CMD_SHELL_DATA, 175 // Forward commands types 176 CMD_FORWARD_INIT = 2500, 177 CMD_FORWARD_CHECK, 178 CMD_FORWARD_CHECK_RESULT, 179 CMD_FORWARD_ACTIVE_SLAVE, 180 CMD_FORWARD_ACTIVE_MASTER, 181 CMD_FORWARD_DATA, 182 CMD_FORWARD_FREE_CONTEXT, 183 CMD_FORWARD_LIST, 184 CMD_FORWARD_REMOVE, 185 CMD_FORWARD_SUCCESS, 186 // File commands 187 CMD_FILE_INIT = 3000, 188 CMD_FILE_CHECK, 189 CMD_FILE_BEGIN, 190 CMD_FILE_DATA, 191 CMD_FILE_FINISH, 192 CMD_APP_SIDELOAD, 193 CMD_FILE_MODE, 194 CMD_DIR_MODE, 195 // App commands 196 CMD_APP_INIT = 3500, 197 CMD_APP_CHECK, 198 CMD_APP_BEGIN, 199 CMD_APP_DATA, 200 CMD_APP_FINISH, 201 CMD_APP_UNINSTALL, 202 203 // deprecated, remove later 204 CMD_UNITY_JPID = CMD_JDWP_LIST, 205 206 // Flashd commands 207 CMD_FLASHD_UPDATE_INIT = 4000, 208 CMD_FLASHD_FLASH_INIT, 209 CMD_FLASHD_CHECK, 210 CMD_FLASHD_BEGIN, 211 CMD_FLASHD_DATA, 212 CMD_FLASHD_FINISH, 213 CMD_FLASHD_ERASE, 214 CMD_FLASHD_FORMAT, 215 CMD_FLASHD_PROGRESS, 216 }; 217 218 enum UsbProtocolOption { 219 USB_OPTION_HEADER = 1, 220 USB_OPTION_RESET = 2, 221 USB_OPTION_RESERVE4 = 4, 222 USB_OPTION_RESERVE8 = 8, 223 USB_OPTION_RESERVE16 = 16, 224 }; 225 // ################################### struct define ################################### 226 #pragma pack(push) 227 #pragma pack(1) 228 229 struct USBHead { 230 uint8_t flag[2]; 231 uint8_t option; 232 uint32_t sessionId; 233 uint32_t dataSize; 234 }; 235 236 struct AsyncParam { 237 void *context; // context=hsession or hchannel 238 uint32_t sid; // sessionId/channelId 239 void *thisClass; // caller's class ptr 240 uint16_t method; 241 int dataSize; 242 void *data; // put it in the last 243 }; 244 245 struct TaskInformation { 246 uint8_t taskType; 247 uint32_t sessionId; 248 uint32_t channelId; 249 bool hasInitial; 250 bool taskStop; 251 bool taskFree; 252 bool serverOrDaemon; 253 bool masterSlave; 254 uv_loop_t *runLoop; 255 void *taskClass; 256 void *ownerSessionClass; 257 uint32_t closeRetryCount; 258 bool channelTask; 259 void *channelClass; 260 }; 261 using HTaskInfo = TaskInformation *; 262 263 #pragma pack(pop) 264 265 #ifdef HDC_HOST 266 struct HostUSBEndpoint { HostUSBEndpointHostUSBEndpoint267 HostUSBEndpoint() 268 { 269 endpoint = 0; 270 sizeEpBuf = 16384; // MAX_USBFFS_BULK 271 transfer = libusb_alloc_transfer(0); 272 isShutdown = true; 273 isComplete = true; 274 bulkInOut = false; 275 (void)memset_s(buf, sizeEpBuf, 0, sizeEpBuf); 276 } ~HostUSBEndpointHostUSBEndpoint277 ~HostUSBEndpoint() 278 { 279 libusb_free_transfer(transfer); 280 } 281 uint8_t endpoint; 282 uint8_t buf[16384]; // MAX_USBFFS_BULK 283 bool isComplete; 284 bool isShutdown; 285 bool bulkInOut; // true is bulkIn 286 uint16_t sizeEpBuf; 287 std::mutex mutexIo; 288 std::mutex mutexCb; 289 condition_variable cv; 290 libusb_transfer *transfer; 291 }; 292 #endif 293 294 struct HdcUSB { 295 #ifdef HDC_HOST 296 libusb_context *ctxUSB = nullptr; // child-use, main null 297 libusb_device *device; 298 libusb_device_handle *devHandle; 299 uint16_t retryCount; 300 uint8_t devId; 301 uint8_t busId; 302 uint8_t interfaceNumber; 303 std::string serialNumber; 304 std::string usbMountPoint; 305 HostUSBEndpoint hostBulkIn; 306 HostUSBEndpoint hostBulkOut; 307 308 #else 309 // usb accessory FunctionFS 310 // USB main thread use, sub-thread disable, sub-thread uses the main thread USB handle 311 int bulkOut; // EP1 device recv 312 int bulkIn; // EP2 device send 313 #endif 314 uint32_t payloadSize; 315 uint16_t wMaxPacketSizeSend; 316 bool resetIO; // if true, must break write and read,default false 317 std::mutex lockDeviceHandle; 318 std::mutex lockSendUsbBlock; 319 }; 320 using HUSB = struct HdcUSB *; 321 322 #ifdef HDC_SUPPORT_UART 323 struct HdcUART { 324 #ifdef HDC_HOST 325 std::string serialPort; 326 std::thread readThread; 327 uint16_t retryCount = 0; 328 #endif // HDC_HOST 329 330 #ifdef _WIN32 331 OVERLAPPED ovWrite; 332 OVERLAPPED ovRead; 333 HANDLE devUartHandle = INVALID_HANDLE_VALUE; 334 #else 335 // we also make this for daemon side 336 int devUartHandle = -1; 337 #endif 338 // if we want to cancel io (read thread exit) 339 bool ioCancel = false; 340 uint32_t dispatchedPackageIndex = 0; 341 bool resetIO = false; // if true, must break write and read,default false 342 uint64_t packageIndex = 0; 343 std::atomic_size_t streamSize = 0; // for debug only 344 HdcUART(); 345 ~HdcUART(); 346 }; 347 using HUART = struct HdcUART *; 348 #endif 349 350 struct HdcSession { 351 bool serverOrDaemon; // instance of daemon or server 352 bool handshakeOK; // Is an expected peer side 353 bool isDead; 354 bool voteReset; 355 bool isCheck = false; 356 std::string connectKey; 357 uint8_t connType; // ConnType 358 uint32_t sessionId; 359 std::atomic<uint32_t> ref; 360 uint8_t uvHandleRef; // libuv handle ref -- just main thread now 361 uint8_t uvChildRef; // libuv handle ref -- just main thread now 362 bool childCleared; 363 std::map<uint32_t, HTaskInfo> *mapTask; 364 // class ptr 365 void *classInstance; // HdcSessionBase instance, HdcServer or HdcDaemon 366 void *classModule; // Communicate module, TCP or USB instance,HdcDaemonUSB HdcDaemonTCP etc... 367 // io cache 368 int bufSize; // total buffer size 369 int availTailIndex; // buffer available data size 370 uint8_t *ioBuf; 371 // auth 372 std::list<void *> *listKey; // rsa private or publickey list 373 uint8_t authKeyIndex; 374 std::string tokenRSA; // SHA_DIGEST_LENGTH+1==21 375 // child work 376 uv_loop_t childLoop; // run in work thread 377 // pipe0 in main thread(hdc server mainloop), pipe1 in work thread 378 uv_tcp_t ctrlPipe[2]; // control channel 379 int ctrlFd[2]; // control channel socketpair 380 // data channel(TCP with socket, USB with thread forward) 381 uv_tcp_t dataPipe[2]; 382 int dataFd[2]; // data channel socketpair 383 uv_tcp_t hChildWorkTCP; // work channel,separate thread for server/daemon 384 uv_os_sock_t fdChildWorkTCP; 385 // usb handle 386 HUSB hUSB; 387 #ifdef HDC_SUPPORT_UART 388 HUART hUART = nullptr; 389 #endif 390 // tcp handle 391 uv_tcp_t hWorkTCP; 392 uv_thread_t hWorkThread; 393 uv_thread_t hWorkChildThread; 394 std::mutex mapTaskMutex; ToDebugStringHdcSession395 std::string ToDebugString() 396 { 397 std::ostringstream oss; 398 oss << "HdcSession ["; 399 oss << " serverOrDaemon:" << serverOrDaemon; 400 oss << " sessionId:" << sessionId; 401 oss << " handshakeOK:" << handshakeOK; 402 oss << " connectKey:" << connectKey; 403 oss << " connType:" << unsigned(connType); 404 oss << " ]"; 405 return oss.str(); 406 } 407 HdcSessionHdcSession408 HdcSession() 409 { 410 serverOrDaemon = false; 411 handshakeOK = false; 412 isDead = false; 413 voteReset = false; 414 connectKey = ""; 415 connType = CONN_USB; 416 sessionId = 0; 417 ref = 0; 418 uvHandleRef = 0; 419 uvChildRef = 0; 420 childCleared = false; 421 mapTask = nullptr; 422 classInstance = nullptr; 423 classModule = nullptr; 424 bufSize = 0; 425 ioBuf = nullptr; 426 availTailIndex = 0; 427 listKey = nullptr; 428 authKeyIndex = 0; 429 tokenRSA = ""; 430 hUSB = nullptr; 431 #ifdef HDC_SUPPORT_UART 432 hUART = nullptr; 433 #endif 434 } 435 ~HdcSessionHdcSession436 ~HdcSession() 437 { 438 if (mapTask) { 439 delete mapTask; 440 mapTask = nullptr; 441 } 442 if (listKey) { 443 delete listKey; 444 listKey = nullptr; 445 } 446 } 447 }; 448 using HSession = struct HdcSession *; 449 450 enum class RemoteType { 451 REMOTE_NONE = 0, 452 REMOTE_FILE = 1, 453 REMOTE_APP = 2, 454 }; 455 456 struct HdcChannel { 457 void *clsChannel; // ptr Class of serverForClient or client 458 uint32_t channelId; 459 std::string connectKey; 460 uv_tcp_t hWorkTCP; // work channel for client, forward channel for server 461 uv_thread_t hWorkThread; 462 uint8_t uvHandleRef = 0; // libuv handle ref -- just main thread now 463 bool handshakeOK; 464 bool isDead; 465 bool serverOrClient; // client's channel/ server's channel 466 bool childCleared; 467 bool interactiveShellMode; // Is shell interactive mode 468 bool keepAlive; // channel will not auto-close by server 469 std::atomic<uint32_t> ref; 470 uint32_t targetSessionId; 471 // child work 472 uv_tcp_t hChildWorkTCP; // work channel for server, no use in client 473 uv_os_sock_t fdChildWorkTCP; 474 // read io cache 475 int bufSize; // total buffer size 476 int availTailIndex; // buffer available data size 477 uint8_t *ioBuf; 478 // std 479 uv_tty_t stdinTty; 480 uv_tty_t stdoutTty; 481 char bufStd[128]; 482 bool isCheck = false; 483 std::string key; 484 RemoteType remote = RemoteType::REMOTE_NONE; 485 bool fromClient = false; 486 }; 487 using HChannel = struct HdcChannel *; 488 489 struct HdcDaemonInformation { 490 uint8_t connType; 491 uint8_t connStatus; 492 std::string connectKey; 493 std::string usbMountPoint; 494 std::string devName; 495 HSession hSession; 496 std::string version; 497 }; 498 using HDaemonInfo = struct HdcDaemonInformation *; 499 500 struct HdcForwardInformation { 501 std::string taskString; 502 bool forwardDirection; // true for forward, false is reverse; 503 uint32_t sessionId; 504 uint32_t channelId; 505 }; 506 using HForwardInfo = struct HdcForwardInformation *; 507 } 508 #endif 509