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