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 }; 163 164 enum HdcCommand { 165 // core commands types 166 CMD_KERNEL_HELP = 0, 167 CMD_KERNEL_HANDSHAKE, 168 CMD_KERNEL_CHANNEL_CLOSE, 169 CMD_KERNEL_SERVER_KILL, 170 CMD_KERNEL_TARGET_DISCOVER, 171 CMD_KERNEL_TARGET_LIST, 172 CMD_KERNEL_TARGET_ANY, 173 CMD_KERNEL_TARGET_CONNECT, 174 CMD_KERNEL_TARGET_DISCONNECT, 175 CMD_KERNEL_ECHO, 176 CMD_KERNEL_ECHO_RAW, 177 CMD_KERNEL_ENABLE_KEEPALIVE, 178 CMD_KERNEL_WAKEUP_SLAVETASK, 179 CMD_CHECK_SERVER, 180 CMD_CHECK_DEVICE, 181 CMD_WAIT_FOR, 182 // One-pass simple commands 183 CMD_UNITY_COMMAND_HEAD = 1000, // not use 184 CMD_UNITY_EXECUTE, 185 CMD_UNITY_REMOUNT, 186 CMD_UNITY_REBOOT, 187 CMD_UNITY_RUNMODE, 188 CMD_UNITY_HILOG, 189 CMD_UNITY_TERMINATE, 190 CMD_UNITY_ROOTRUN, 191 CMD_JDWP_LIST, 192 CMD_JDWP_TRACK, 193 CMD_UNITY_COMMAND_TAIL, // not use 194 // It will be separated from unity in the near future 195 CMD_UNITY_BUGREPORT_INIT, 196 CMD_UNITY_BUGREPORT_DATA, 197 // Shell commands types 198 CMD_SHELL_INIT = 2000, 199 CMD_SHELL_DATA, 200 // Forward commands types 201 CMD_FORWARD_INIT = 2500, 202 CMD_FORWARD_CHECK, 203 CMD_FORWARD_CHECK_RESULT, 204 CMD_FORWARD_ACTIVE_SLAVE, 205 CMD_FORWARD_ACTIVE_MASTER, 206 CMD_FORWARD_DATA, 207 CMD_FORWARD_FREE_CONTEXT, 208 CMD_FORWARD_LIST, 209 CMD_FORWARD_REMOVE, 210 CMD_FORWARD_SUCCESS, 211 // File commands 212 CMD_FILE_INIT = 3000, 213 CMD_FILE_CHECK, 214 CMD_FILE_BEGIN, 215 CMD_FILE_DATA, 216 CMD_FILE_FINISH, 217 CMD_APP_SIDELOAD, 218 CMD_FILE_MODE, 219 CMD_DIR_MODE, 220 // App commands 221 CMD_APP_INIT = 3500, 222 CMD_APP_CHECK, 223 CMD_APP_BEGIN, 224 CMD_APP_DATA, 225 CMD_APP_FINISH, 226 CMD_APP_UNINSTALL, 227 228 // deprecated, remove later 229 CMD_UNITY_JPID = CMD_JDWP_LIST, 230 231 // Flashd commands 232 CMD_FLASHD_UPDATE_INIT = 4000, 233 CMD_FLASHD_FLASH_INIT, 234 CMD_FLASHD_CHECK, 235 CMD_FLASHD_BEGIN, 236 CMD_FLASHD_DATA, 237 CMD_FLASHD_FINISH, 238 CMD_FLASHD_ERASE, 239 CMD_FLASHD_FORMAT, 240 CMD_FLASHD_PROGRESS, 241 }; 242 243 enum UsbProtocolOption { 244 USB_OPTION_HEADER = 1, 245 USB_OPTION_RESET = 2, 246 USB_OPTION_RESERVE4 = 4, 247 USB_OPTION_RESERVE8 = 8, 248 USB_OPTION_RESERVE16 = 16, 249 }; 250 // ################################### struct define ################################### 251 #pragma pack(push) 252 #pragma pack(1) 253 254 struct USBHead { 255 uint8_t flag[2]; 256 uint8_t option; 257 uint32_t sessionId; 258 uint32_t dataSize; 259 }; 260 261 struct AsyncParam { 262 void *context; // context=hsession or hchannel 263 uint32_t sid; // sessionId/channelId 264 void *thisClass; // caller's class ptr 265 uint16_t method; 266 int dataSize; 267 void *data; // put it in the last 268 }; 269 270 struct TaskInformation { 271 uint8_t taskType; 272 uint32_t sessionId; 273 uint32_t channelId; 274 bool hasInitial; 275 bool taskStop; 276 bool taskFree; 277 bool serverOrDaemon; 278 bool masterSlave; 279 uv_loop_t *runLoop; 280 void *taskClass; 281 void *ownerSessionClass; 282 uint32_t closeRetryCount; 283 bool channelTask; 284 void *channelClass; 285 }; 286 using HTaskInfo = TaskInformation *; 287 288 #pragma pack(pop) 289 290 #ifdef HDC_HOST 291 struct HostUSBEndpoint { HostUSBEndpointHostUSBEndpoint292 HostUSBEndpoint() 293 { 294 endpoint = 0; 295 sizeEpBuf = 62464; // MAX_USBFFS_BULK 296 transfer = libusb_alloc_transfer(0); 297 isShutdown = true; 298 isComplete = true; 299 bulkInOut = false; 300 buf = new (std::nothrow) uint8_t[sizeEpBuf]; 301 (void)memset_s(buf, sizeEpBuf, 0, sizeEpBuf); 302 } ~HostUSBEndpointHostUSBEndpoint303 ~HostUSBEndpoint() 304 { 305 libusb_free_transfer(transfer); 306 delete[] buf; 307 } 308 uint8_t endpoint; 309 uint8_t *buf; // MAX_USBFFS_BULK 310 bool isComplete; 311 bool isShutdown; 312 bool bulkInOut; // true is bulkIn 313 uint16_t sizeEpBuf; 314 std::mutex mutexIo; 315 std::mutex mutexCb; 316 condition_variable cv; 317 libusb_transfer *transfer; 318 }; 319 #endif 320 321 struct HdcUSB { 322 #ifdef HDC_HOST 323 libusb_context *ctxUSB = nullptr; // child-use, main null 324 libusb_device *device; 325 libusb_device_handle *devHandle; 326 uint16_t retryCount; 327 uint8_t devId; 328 uint8_t busId; 329 uint8_t interfaceNumber; 330 std::string serialNumber; 331 std::string usbMountPoint; 332 HostUSBEndpoint hostBulkIn; 333 HostUSBEndpoint hostBulkOut; 334 335 #else 336 // usb accessory FunctionFS 337 // USB main thread use, sub-thread disable, sub-thread uses the main thread USB handle 338 int bulkOut; // EP1 device recv 339 int bulkIn; // EP2 device send 340 #endif 341 uint32_t payloadSize; 342 uint16_t wMaxPacketSizeSend; 343 bool resetIO; // if true, must break write and read,default false 344 std::mutex lockDeviceHandle; 345 std::mutex lockSendUsbBlock; 346 }; 347 using HUSB = struct HdcUSB *; 348 349 #ifdef HDC_SUPPORT_UART 350 struct HdcUART { 351 #ifdef HDC_HOST 352 std::string serialPort; 353 std::thread readThread; 354 uint16_t retryCount = 0; 355 #endif // HDC_HOST 356 357 #ifdef _WIN32 358 OVERLAPPED ovWrite; 359 OVERLAPPED ovRead; 360 HANDLE devUartHandle = INVALID_HANDLE_VALUE; 361 #else 362 // we also make this for daemon side 363 int devUartHandle = -1; 364 #endif 365 // if we want to cancel io (read thread exit) 366 bool ioCancel = false; 367 uint32_t dispatchedPackageIndex = 0; 368 bool resetIO = false; // if true, must break write and read,default false 369 uint64_t packageIndex = 0; 370 std::atomic_size_t streamSize = 0; // for debug only 371 HdcUART(); 372 ~HdcUART(); 373 }; 374 using HUART = struct HdcUART *; 375 #endif 376 377 struct HdcSession { 378 bool serverOrDaemon; // instance of daemon or server 379 bool handshakeOK; // Is an expected peer side 380 bool isDead; 381 bool voteReset; 382 bool isCheck = false; 383 std::string connectKey; 384 uint8_t connType; // ConnType 385 uint32_t sessionId; 386 std::atomic<uint32_t> ref; 387 uint8_t uvHandleRef; // libuv handle ref -- just main thread now 388 uint8_t uvChildRef; // libuv handle ref -- just main thread now 389 bool childCleared; 390 std::map<uint32_t, HTaskInfo> *mapTask; 391 // class ptr 392 void *classInstance; // HdcSessionBase instance, HdcServer or HdcDaemon 393 void *classModule; // Communicate module, TCP or USB instance,HdcDaemonUSB HdcDaemonTCP etc... 394 // io cache 395 int bufSize; // total buffer size 396 int availTailIndex; // buffer available data size 397 uint8_t *ioBuf; 398 // auth 399 std::list<void *> *listKey; // rsa private or publickey list 400 uint8_t authKeyIndex; 401 std::string tokenRSA; // SHA_DIGEST_LENGTH+1==21 402 // child work 403 uv_loop_t childLoop; // run in work thread 404 // pipe0 in main thread(hdc server mainloop), pipe1 in work thread 405 uv_poll_t *pollHandle[2]; // control channel 406 int ctrlFd[2]; // control channel socketpair 407 // data channel(TCP with socket, USB with thread forward) 408 uv_tcp_t dataPipe[2]; 409 int dataFd[2]; // data channel socketpair 410 uv_tcp_t hChildWorkTCP; // work channel,separate thread for server/daemon 411 uv_os_sock_t fdChildWorkTCP; 412 // usb handle 413 HUSB hUSB; 414 #ifdef HDC_SUPPORT_UART 415 HUART hUART = nullptr; 416 #endif 417 // tcp handle 418 uv_tcp_t hWorkTCP; 419 uv_thread_t hWorkThread; 420 uv_thread_t hWorkChildThread; 421 std::mutex mapTaskMutex; ToDebugStringHdcSession422 std::string ToDebugString() 423 { 424 std::ostringstream oss; 425 oss << "HdcSession ["; 426 oss << " serverOrDaemon:" << serverOrDaemon; 427 oss << " sessionId:" << sessionId; 428 oss << " handshakeOK:" << handshakeOK; 429 oss << " connectKey:" << connectKey; 430 oss << " connType:" << unsigned(connType); 431 oss << " ]"; 432 return oss.str(); 433 } 434 HdcSessionHdcSession435 HdcSession() 436 { 437 serverOrDaemon = false; 438 handshakeOK = false; 439 isDead = false; 440 voteReset = false; 441 connectKey = ""; 442 connType = CONN_USB; 443 sessionId = 0; 444 ref = 0; 445 uvHandleRef = 0; 446 uvChildRef = 0; 447 childCleared = false; 448 mapTask = nullptr; 449 classInstance = nullptr; 450 classModule = nullptr; 451 bufSize = 0; 452 ioBuf = nullptr; 453 availTailIndex = 0; 454 listKey = nullptr; 455 authKeyIndex = 0; 456 tokenRSA = ""; 457 hUSB = nullptr; 458 (void)memset_s(pollHandle, sizeof(pollHandle), 0, sizeof(pollHandle)); 459 (void)memset_s(ctrlFd, sizeof(ctrlFd), 0, sizeof(ctrlFd)); 460 (void)memset_s(dataFd, sizeof(dataFd), 0, sizeof(dataFd)); 461 #ifdef HDC_SUPPORT_UART 462 hUART = nullptr; 463 #endif 464 } 465 ~HdcSessionHdcSession466 ~HdcSession() 467 { 468 if (mapTask) { 469 delete mapTask; 470 mapTask = nullptr; 471 } 472 if (listKey) { 473 delete listKey; 474 listKey = nullptr; 475 } 476 } 477 }; 478 using HSession = struct HdcSession *; 479 480 enum class RemoteType { 481 REMOTE_NONE = 0, 482 REMOTE_FILE = 1, 483 REMOTE_APP = 2, 484 }; 485 486 struct HdcChannel { 487 void *clsChannel; // ptr Class of serverForClient or client 488 uint32_t channelId; 489 std::string connectKey; 490 uv_tcp_t hWorkTCP; // work channel for client, forward channel for server 491 uv_thread_t hWorkThread; 492 uint8_t uvHandleRef = 0; // libuv handle ref -- just main thread now 493 bool handshakeOK; 494 bool isDead; 495 bool serverOrClient; // client's channel/ server's channel 496 bool childCleared; 497 bool interactiveShellMode; // Is shell interactive mode 498 bool keepAlive; // channel will not auto-close by server 499 std::atomic<uint32_t> ref; 500 uint32_t targetSessionId; 501 // child work 502 uv_tcp_t hChildWorkTCP; // work channel for server, no use in client 503 uv_os_sock_t fdChildWorkTCP; 504 // read io cache 505 int bufSize; // total buffer size 506 int availTailIndex; // buffer available data size 507 uint8_t *ioBuf; 508 // std 509 uv_tty_t stdinTty; 510 uv_tty_t stdoutTty; 511 char bufStd[128]; 512 bool isCheck = false; 513 std::string key; 514 RemoteType remote = RemoteType::REMOTE_NONE; 515 bool fromClient = false; 516 bool connectLocalDevice = false; 517 }; 518 using HChannel = struct HdcChannel *; 519 520 struct HdcDaemonInformation { 521 uint8_t connType; 522 uint8_t connStatus; 523 std::string connectKey; 524 std::string usbMountPoint; 525 std::string devName; 526 HSession hSession; 527 std::string version; 528 }; 529 using HDaemonInfo = struct HdcDaemonInformation *; 530 531 struct HdcForwardInformation { 532 std::string taskString; 533 bool forwardDirection; // true for forward, false is reverse; 534 uint32_t sessionId; 535 uint32_t channelId; 536 }; 537 using HForwardInfo = struct HdcForwardInformation *; 538 } 539 #endif 540