• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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