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