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