• 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 #include "define_enum.h"
24 #include "uv_status.h"
25 #include "heartbeat.h"
26 #include "securec.h"
27 #ifdef HDC_HOST
28 #include <libusb.h>
29 #endif
30 #include <list>
31 
32 namespace Hdc {
33 
MaskString(const string & str)34 static string MaskString(const string &str)
35 {
36     if (str.empty()) {
37         return str;
38     }
39     size_t len = str.length();
40     if (len <= 6) {  // 6: 当字符串长度小于等于6时,只保留首尾各一个字符, 掩码的个数为字符的长度
41         return std::string(1, str.front()) + std::string(len, '*') + std::string(1, str.back());
42     } else {
43         // 3, 6: 对于较长的字符串,保留首尾各三个字符,掩码的个数为6
44         return str.substr(0, 3) + std::string(6, '*') + str.substr(len - 3)  + "(L:" + std::to_string(len) + ")";
45     }
46 }
47 
48 #ifndef TEMP_FAILURE_RETRY
49 #define TEMP_FAILURE_RETRY(exp) ({         \
50     __typeof__(exp) _rc;                   \
51     do {                                   \
52         _rc = (exp);                       \
53     } while (_rc == -1 && errno == EINTR); \
54     _rc; })
55 #endif
56 
57 // hitrace will increase ipc thread to upper hdcd memory
58 // IPC function SetMaxWorkThreadNum can limit thread num, default 16 threads
59 #if defined(HDC_TRACE_TEST) && defined(__OHOS__) // default close, change to open by HDC_TRACE
60 #define StartTracePoint(value) StartTrace(HITRACE_TAG_HDCD, value)
61 #define FinishTracePoint()     FinishTrace(HITRACE_TAG_HDCD)
62 #define StartTraceScope(value) HITRACE_METER_NAME(HITRACE_TAG_HDCD, value)
63 #else
64 #define StartTracePoint(value)
65 #define FinishTracePoint()
66 #define StartTraceScope(value)
67 #endif
68 
69 // ################################### struct define ###################################
70 #pragma pack(push)
71 #pragma pack(1)
72 
73 struct USBHead {
74     uint8_t flag[2];
75     uint8_t option;
76     uint32_t sessionId;
77     uint32_t dataSize;
78 };
79 
80 struct AsyncParam {
81     void *context;    // context=hsession or hchannel
82     uint32_t sid;     // sessionId/channelId
83     void *thisClass;  // caller's class ptr
84     uint16_t method;
85     int dataSize;
86     void *data;  // put it in the last
87 };
88 
89 struct TaskInformation {
90     uint8_t taskType;
91     uint32_t sessionId;
92     uint32_t channelId;
93     bool hasInitial;
94     bool taskStop;
95     bool taskFree;
96     bool serverOrDaemon; // true is server, false is daemon
97     bool masterSlave;
98     uv_loop_t *runLoop;
99     LoopStatus *runLoopStatus;
100     void *taskClass;
101     void *ownerSessionClass;
102     uint32_t closeRetryCount;
103     bool channelTask;
104     void *channelClass;
105     uint8_t debugRelease; // 0:allApp 1:debugApp 2:releaseApp
106     bool isStableBuf;
107     bool isCleared; // true: RemoveInstanceTask OP_CLEAR is called
108 };
109 using HTaskInfo = TaskInformation *;
110 
111 #pragma pack(pop)
112 
113 #ifdef HDC_HOST
114 struct HostUSBEndpoint {
HostUSBEndpointHostUSBEndpoint115     HostUSBEndpoint(uint32_t epBufSize)
116     {
117         endpoint = 0;
118         sizeEpBuf = epBufSize;  // MAX_USBFFS_BULK
119         transfer = libusb_alloc_transfer(0);
120         isShutdown = true;
121         isComplete = true;
122         bulkInOut = false;
123         buf = new (std::nothrow) uint8_t[sizeEpBuf];
124         (void)memset_s(buf, sizeEpBuf, 0, sizeEpBuf);
125     }
~HostUSBEndpointHostUSBEndpoint126     ~HostUSBEndpoint()
127     {
128         libusb_free_transfer(transfer);
129         delete[] buf;
130     }
131     uint8_t endpoint;
132     uint8_t *buf;  // MAX_USBFFS_BULK
133     bool isComplete;
134     bool isShutdown;
135     bool bulkInOut;  // true is bulkIn
136     uint32_t sizeEpBuf;
137     std::mutex mutexIo;
138     std::mutex mutexCb;
139     std::condition_variable cv;
140     libusb_transfer *transfer;
141 };
142 #endif
143 
144 struct HdcUSB {
145 #ifdef HDC_HOST
146     libusb_context *ctxUSB = nullptr;  // child-use, main null
147     libusb_device *device = nullptr;
148     libusb_device_handle *devHandle = nullptr;
149     uint16_t retryCount;
150     uint8_t devId;
151     uint8_t busId;
152     uint8_t interfaceNumber;
153     std::string serialNumber;
154     std::string usbMountPoint;
155     HostUSBEndpoint hostBulkIn;
156     HostUSBEndpoint hostBulkOut;
HdcUSBHdcUSB157     HdcUSB() : hostBulkIn(513 * 1024), hostBulkOut(512 * 1024) {} // 513: 512 + 1, 1024: 1KB
158     // 512 * 1024 + 1024 = 513 * 1024, MAX_USBFFS_BULK: 512 * 1024
159 
160 #else
161     // usb accessory FunctionFS
162     // USB main thread use, sub-thread disable, sub-thread uses the main thread USB handle
163     int bulkOut;  // EP1 device recv
164     bool isBulkOutClosing;
165     int bulkIn;   // EP2 device send
166     bool isBulkInClosing;
167 #endif
168     uint32_t payloadSize;
169     uint16_t wMaxPacketSizeSend;
170     bool resetIO;  // if true, must break write and read,default false
171     std::mutex lockDeviceHandle;
172     std::mutex lockSendUsbBlock;
173 };
174 using HUSB = struct HdcUSB *;
175 
176 #ifdef HDC_SUPPORT_UART
177 struct HdcUART {
178 #ifdef HDC_HOST
179     std::string serialPort;
180     std::thread readThread;
181     uint16_t retryCount = 0;
182 #endif // HDC_HOST
183 
184 #ifdef _WIN32
185     OVERLAPPED ovWrite;
186     OVERLAPPED ovRead;
187     HANDLE devUartHandle = INVALID_HANDLE_VALUE;
188 #else
189     // we also make this for daemon side
190     int devUartHandle = -1;
191 #endif
192     // if we want to cancel io (read thread exit)
193     bool ioCancel = false;
194     uint32_t dispatchedPackageIndex = 0;
195     bool resetIO = false; // if true, must break write and read,default false
196     uint64_t packageIndex = 0;
197     std::atomic_size_t streamSize = 0; // for debug only
198     HdcUART();
199     ~HdcUART();
200 };
201 using HUART = struct HdcUART *;
202 #endif
203 struct HdcSessionStat {
204     // bytes successed send to hSession->dataFd[STREAM_MAIN]
205     std::atomic<uint64_t> dataSendBytes;
206     // bytes successed read from hSession->dataPipe[STREAM_WORK]
207     std::atomic<uint64_t> dataRecvBytes;
208 };
209 
210 struct HdcSession {
211     bool serverOrDaemon;  // instance of daemon or server, true is server, false is daemon
212     bool handshakeOK = false;     // Is an expected peer side
213     bool isDead;
214     bool voteReset;
215     bool isCheck = false;
216     std::string connectKey;
217     uint8_t connType;  // ConnType
218     uint32_t sessionId;
219     std::atomic<uint32_t> ref;
220     uint8_t uvHandleRef;  // libuv handle ref -- just main thread now
221     uint8_t uvChildRef;   // libuv handle ref -- just main thread now
222     bool childCleared;
223     std::map<uint32_t, HTaskInfo> *mapTask;
224     std::atomic<uint32_t> clearTaskTimes;
225     // class ptr
226     void *classInstance;  //  HdcSessionBase instance, HdcServer or HdcDaemon
227     void *classModule;    //  Communicate module, TCP or USB instance,HdcDaemonUSB HdcDaemonTCP etc...
228     // io cache
229     int bufSize;         // total buffer size
230     int availTailIndex;  // buffer available data size
231     uint8_t *ioBuf;
232     // auth
233     std::list<void *> *listKey;  // rsa private or publickey list
234     uint8_t authKeyIndex;
235     std::string tokenRSA;  // SHA_DIGEST_LENGTH+1==21
236     // child work
237     uv_loop_t childLoop;  // run in work thread
238     LoopStatus childLoopStatus;
239     // pipe0 in main thread(hdc server mainloop), pipe1 in work thread
240     uv_poll_t *pollHandle[2];  // control channel
241     int ctrlFd[2];         // control channel socketpair
242     // data channel(TCP with socket, USB with thread forward)
243     uv_tcp_t dataPipe[2];
244     int dataFd[2];           // data channel socketpair
245     uv_tcp_t hChildWorkTCP;  // work channel,separate thread for server/daemon
246     uv_os_sock_t fdChildWorkTCP;
247     // usb handle
248     HUSB hUSB;
249     bool sslHandshake = false;
250     void *classSSL = nullptr;
251 #ifdef HDC_SUPPORT_UART
252     HUART hUART = nullptr;
253 #endif
254     // tcp handle
255     uv_tcp_t hWorkTCP;
256     uv_thread_t hWorkThread;
257     uv_thread_t hWorkChildThread;
258     std::mutex mapTaskMutex;
259     AuthVerifyType verifyType;
260     bool isSoftReset; // for daemon, Used to record whether a reset command has been received
261     HdcHeartbeat heartbeat;
262     bool supportEncrypt = false;
263     uv_timer_t heartbeatTimer;
264 
265     HdcSessionStat stat;
266 #ifdef HDC_HOST
267     bool isRunningOk;
268     std::string faultInfo;
269     uint64_t commandCount = 0;
ToDisplayConnectionStrHdcSession270     std::string ToDisplayConnectionStr()
271     {
272         std::ostringstream oss;
273         oss << "HdcServer [";
274         oss << " sessionId:" << sessionId;
275         oss << " connectKey:" << Hdc::MaskString(connectKey);
276         oss << " connType:" << unsigned(connType);
277         oss << " connect state:" << isRunningOk;
278         oss << " faultInfo:" << faultInfo;
279         oss << " commandCount:" << commandCount;
280         oss << " ]";
281         return oss.str();
282     }
283 #endif
ToDebugStringHdcSession284     std::string ToDebugString()
285     {
286         std::ostringstream oss;
287         oss << "HdcSession [";
288         oss << " serverOrDaemon:" << serverOrDaemon;
289         oss << " sessionId:" << sessionId;
290         oss << " handshakeOK:" << handshakeOK;
291         oss << " connectKey:" << Hdc::MaskString(connectKey);
292         oss << " connType:" << unsigned(connType);
293         oss << " ]";
294         return oss.str();
295     }
296 
HdcSessionHdcSession297     HdcSession() : serverOrDaemon(false), handshakeOK(false), isDead(false),
298                    voteReset(false), childLoopStatus(&childLoop, "ChildLoop")
299     {
300         connectKey = "";
301         connType = CONN_USB;
302         sessionId = 0;
303         ref = 0;
304         uvHandleRef = 0;
305         uvChildRef = 0;
306         childCleared = false;
307         mapTask = nullptr;
308         clearTaskTimes = 0;
309         classInstance = nullptr;
310         classModule = nullptr;
311         bufSize = 0;
312         ioBuf = nullptr;
313         availTailIndex = 0;
314         listKey = nullptr;
315         authKeyIndex = 0;
316         tokenRSA = "";
317         hUSB = nullptr;
318         (void)memset_s(pollHandle, sizeof(pollHandle), 0, sizeof(pollHandle));
319         (void)memset_s(ctrlFd, sizeof(ctrlFd), 0, sizeof(ctrlFd));
320         (void)memset_s(dataFd, sizeof(dataFd), 0, sizeof(dataFd));
321         (void)memset_s(&childLoop, sizeof(childLoop), 0, sizeof(childLoop));
322         (void)memset_s(dataPipe, sizeof(dataPipe), 0, sizeof(dataPipe));
323         (void)memset_s(&hChildWorkTCP, sizeof(hChildWorkTCP), 0, sizeof(hChildWorkTCP));
324         (void)memset_s(&fdChildWorkTCP, sizeof(fdChildWorkTCP), 0, sizeof(fdChildWorkTCP));
325         (void)memset_s(&stat, sizeof(stat), 0, sizeof(stat));
326 #ifdef HDC_SUPPORT_UART
327         hUART = nullptr;
328 #endif
329         verifyType = AuthVerifyType::RSA_3072_SHA512;
330         isSoftReset = false;
331 #ifdef HDC_HOST
332         isRunningOk = true;
333         faultInfo = "";
334 #endif
335     }
336 
~HdcSessionHdcSession337     ~HdcSession()
338     {
339         if (mapTask) {
340             delete mapTask;
341             mapTask = nullptr;
342         }
343         if (listKey) {
344             delete listKey;
345             listKey = nullptr;
346         }
347     }
348 };
349 using HSession = struct HdcSession *;
350 
351 enum class RemoteType {
352     REMOTE_NONE = 0,
353     REMOTE_FILE = 1,
354     REMOTE_APP = 2,
355 };
356 
357 struct HdcChannel {
358     void *clsChannel;  // ptr Class of serverForClient or client
359     uint32_t channelId;
360     std::string connectKey;
361 #ifdef HOST_OHOS
362     bool isUds = false;
363     uv_pipe_t hWorkUds;
364     uv_pipe_t hChildWorkUds;
365 #endif
366     uv_tcp_t hWorkTCP;  // work channel for client, forward channel for server
367     uv_thread_t hWorkThread;
368     uint8_t uvHandleRef = 0;  // libuv handle ref -- just main thread now
369     bool handshakeOK;
370     bool isDead;
371     bool serverOrClient;  // true: server's channel, false: client's channel
372     bool childCleared;
373     bool interactiveShellMode;  // Is shell interactive mode
374     bool keepAlive;             // channel will not auto-close by server
375     std::atomic<uint32_t> ref;
376     uint32_t targetSessionId;
377     // child work
378     uv_tcp_t hChildWorkTCP;  // work channel for server, no use in client
379     uv_os_sock_t fdChildWorkTCP;
380     LoopStatus *loopStatus;
381     // read io cache
382     int bufSize;         // total buffer size
383     int availTailIndex;  // buffer available data size
384     uint8_t *ioBuf;
385     // std
386     uv_tty_t stdinTty;
387     uv_tty_t stdoutTty;
388     char bufStd[128];
389     bool isCheck = false;
390     std::string key;
391     RemoteType remote = RemoteType::REMOTE_NONE;
392     bool fromClient = false;
393     bool connectLocalDevice = false;
394     bool isStableBuf = false;
395     std::atomic<uint32_t> writeFailedTimes;
396 #ifdef HOST_OHOS
397     bool isSupportedKillServerCmd = false;
398 #endif
399 #ifdef HDC_HOST
400     uint64_t startTime = 0;
401     uint64_t endTime = 0;
402     bool isSuccess = false;
403     std::string faultInfo = "";
404     uint16_t commandFlag = 0;
405     std::string commandParameters = "";
406 
ToDisplayChannelStrHdcChannel407     std::string ToDisplayChannelStr()
408     {
409         std::ostringstream oss;
410         oss << "HdcServerForClient [";
411         oss << " channelId:" << channelId;
412         oss << " connectKey:" << Hdc::MaskString(connectKey);
413         oss << " command flag:" << commandFlag;
414         int i = commandParameters.size() - 1;
415         while (i >= 0 && commandParameters[i] == '\0') {
416             commandParameters[i] = ' ';
417             i--;
418         }
419         oss << " command result:" << isSuccess;
420         oss << " command take time:" << (endTime - startTime) << "ms";
421         oss << " faultInfo:" << faultInfo;
422         oss << " ]";
423         return oss.str();
424     }
425 #endif
426 };
427 using HChannel = struct HdcChannel *;
428 
429 struct HdcDaemonInformation {
430     uint8_t connType;
431     uint8_t connStatus;
432     std::string connectKey;
433     std::string usbMountPoint;
434     std::string devName;
435     HSession hSession;
436     std::string version;
437     std::string emgmsg;
438     std::string daemonAuthStatus;
439     std::map<std::string, std::string> daemonFeature;
440     bool inited;
441 };
442 using HDaemonInfo = struct HdcDaemonInformation *;
443 
444 struct HdcForwardInformation {
445     std::string taskString;
446     bool forwardDirection;  // true for forward, false is reverse;
447     uint32_t sessionId;
448     uint32_t channelId;
449     std::string connectKey;
450 };
451 using HForwardInfo = struct HdcForwardInformation *;
452 
453 struct HdcSessionInfo {
454     uint32_t sessionId = 0;
455     HSession hSession = nullptr;
456 
457     // class ptr
458     void *classInstance = nullptr;  //  HdcSessionBase instance, HdcServer or HdcDaemon
459     void *classModule = nullptr;    //  Communicate module, TCP or USB instance,HdcDaemonUSB HdcDaemonTCP etc...
460 };
461 using HSessionInfo = struct HdcSessionInfo *;
462 
463 #ifdef HDC_SUPPORT_ENCRYPT_TCP
464 struct HdcSSLInfo {
465     bool isDaemon;
466     uint32_t sessionId;
467     std::string cipher;
468 };
469 using SSLInfoPtr = struct HdcSSLInfo *;
470 #endif
471 }
472 #endif
473