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