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