• 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     bool isCleared; // true: RemoveInstanceTask OP_CLEAR is called
100 };
101 using HTaskInfo = TaskInformation *;
102 
103 #pragma pack(pop)
104 
105 #ifdef HDC_HOST
106 struct HostUSBEndpoint {
HostUSBEndpointHostUSBEndpoint107     HostUSBEndpoint(uint32_t epBufSize)
108     {
109         endpoint = 0;
110         sizeEpBuf = epBufSize;  // MAX_USBFFS_BULK
111         transfer = libusb_alloc_transfer(0);
112         isShutdown = true;
113         isComplete = true;
114         bulkInOut = false;
115         buf = new (std::nothrow) uint8_t[sizeEpBuf];
116         (void)memset_s(buf, sizeEpBuf, 0, sizeEpBuf);
117     }
~HostUSBEndpointHostUSBEndpoint118     ~HostUSBEndpoint()
119     {
120         libusb_free_transfer(transfer);
121         delete[] buf;
122     }
123     uint8_t endpoint;
124     uint8_t *buf;  // MAX_USBFFS_BULK
125     bool isComplete;
126     bool isShutdown;
127     bool bulkInOut;  // true is bulkIn
128     uint32_t sizeEpBuf;
129     std::mutex mutexIo;
130     std::mutex mutexCb;
131     condition_variable cv;
132     libusb_transfer *transfer;
133 };
134 #endif
135 
136 struct HdcUSB {
137 #ifdef HDC_HOST
138     libusb_context *ctxUSB = nullptr;  // child-use, main null
139     libusb_device *device;
140     libusb_device_handle *devHandle;
141     uint16_t retryCount;
142     uint8_t devId;
143     uint8_t busId;
144     uint8_t interfaceNumber;
145     std::string serialNumber;
146     std::string usbMountPoint;
147     HostUSBEndpoint hostBulkIn;
148     HostUSBEndpoint hostBulkOut;
HdcUSBHdcUSB149     HdcUSB() : hostBulkIn(513 * 1024), hostBulkOut(512 * 1024) {} // 513: 512 + 1, 1024: 1KB
150     // 512 * 1024 + 1024 = 513 * 1024, MAX_USBFFS_BULK: 512 * 1024
151 
152 #else
153     // usb accessory FunctionFS
154     // USB main thread use, sub-thread disable, sub-thread uses the main thread USB handle
155     int bulkOut;  // EP1 device recv
156     int bulkIn;   // EP2 device send
157 #endif
158     uint32_t payloadSize;
159     uint16_t wMaxPacketSizeSend;
160     bool resetIO;  // if true, must break write and read,default false
161     std::mutex lockDeviceHandle;
162     std::mutex lockSendUsbBlock;
163 };
164 using HUSB = struct HdcUSB *;
165 
166 #ifdef HDC_SUPPORT_UART
167 struct HdcUART {
168 #ifdef HDC_HOST
169     std::string serialPort;
170     std::thread readThread;
171     uint16_t retryCount = 0;
172 #endif // HDC_HOST
173 
174 #ifdef _WIN32
175     OVERLAPPED ovWrite;
176     OVERLAPPED ovRead;
177     HANDLE devUartHandle = INVALID_HANDLE_VALUE;
178 #else
179     // we also make this for daemon side
180     int devUartHandle = -1;
181 #endif
182     // if we want to cancel io (read thread exit)
183     bool ioCancel = false;
184     uint32_t dispatchedPackageIndex = 0;
185     bool resetIO = false; // if true, must break write and read,default false
186     uint64_t packageIndex = 0;
187     std::atomic_size_t streamSize = 0; // for debug only
188     HdcUART();
189     ~HdcUART();
190 };
191 using HUART = struct HdcUART *;
192 #endif
193 struct HdcSessionStat {
194     // bytes successed send to hSession->dataFd[STREAM_MAIN]
195     std::atomic<uint64_t> dataSendBytes;
196     // bytes successed read from hSession->dataPipe[STREAM_WORK]
197     std::atomic<uint64_t> dataRecvBytes;
198 };
199 
200 struct HdcSession {
201     bool serverOrDaemon;  // instance of daemon or server
202     bool handshakeOK;     // Is an expected peer side
203     bool isDead;
204     bool voteReset;
205     bool isCheck = false;
206     std::string connectKey;
207     uint8_t connType;  // ConnType
208     uint32_t sessionId;
209     std::atomic<uint32_t> ref;
210     uint8_t uvHandleRef;  // libuv handle ref -- just main thread now
211     uint8_t uvChildRef;   // libuv handle ref -- just main thread now
212     bool childCleared;
213     std::map<uint32_t, HTaskInfo> *mapTask;
214     // class ptr
215     void *classInstance;  //  HdcSessionBase instance, HdcServer or HdcDaemon
216     void *classModule;    //  Communicate module, TCP or USB instance,HdcDaemonUSB HdcDaemonTCP etc...
217     // io cache
218     int bufSize;         // total buffer size
219     int availTailIndex;  // buffer available data size
220     uint8_t *ioBuf;
221     // auth
222     std::list<void *> *listKey;  // rsa private or publickey list
223     uint8_t authKeyIndex;
224     std::string tokenRSA;  // SHA_DIGEST_LENGTH+1==21
225     // child work
226     uv_loop_t childLoop;  // run in work thread
227     // pipe0 in main thread(hdc server mainloop), pipe1 in work thread
228     uv_poll_t *pollHandle[2];  // control channel
229     int ctrlFd[2];         // control channel socketpair
230     // data channel(TCP with socket, USB with thread forward)
231     uv_tcp_t dataPipe[2];
232     int dataFd[2];           // data channel socketpair
233     uv_tcp_t hChildWorkTCP;  // work channel,separate thread for server/daemon
234     uv_os_sock_t fdChildWorkTCP;
235     // usb handle
236     HUSB hUSB;
237 #ifdef HDC_SUPPORT_UART
238     HUART hUART = nullptr;
239 #endif
240     // tcp handle
241     uv_tcp_t hWorkTCP;
242     uv_thread_t hWorkThread;
243     uv_thread_t hWorkChildThread;
244     std::mutex mapTaskMutex;
245     AuthVerifyType verifyType;
246     std::atomic<bool> isNeedDropData; // host: Whether to discard the USB data after it is read
247     std::atomic<uint64_t> dropBytes;
248     bool isSoftReset; // for daemon, Used to record whether a reset command has been received
249 
250     HdcSessionStat stat;
ToDebugStringHdcSession251     std::string ToDebugString()
252     {
253         std::ostringstream oss;
254         oss << "HdcSession [";
255         oss << " serverOrDaemon:" << serverOrDaemon;
256         oss << " sessionId:" << sessionId;
257         oss << " handshakeOK:" << handshakeOK;
258         oss << " connectKey:" << Hdc::MaskString(connectKey);
259         oss << " connType:" << unsigned(connType);
260         oss << " ]";
261         return oss.str();
262     }
263 
HdcSessionHdcSession264     HdcSession():serverOrDaemon(false), handshakeOK(false), isDead(false), voteReset(false)
265     {
266         connectKey = "";
267         connType = CONN_USB;
268         sessionId = 0;
269         ref = 0;
270         uvHandleRef = 0;
271         uvChildRef = 0;
272         childCleared = false;
273         mapTask = nullptr;
274         classInstance = nullptr;
275         classModule = nullptr;
276         bufSize = 0;
277         ioBuf = nullptr;
278         availTailIndex = 0;
279         listKey = nullptr;
280         authKeyIndex = 0;
281         tokenRSA = "";
282         hUSB = nullptr;
283         (void)memset_s(pollHandle, sizeof(pollHandle), 0, sizeof(pollHandle));
284         (void)memset_s(ctrlFd, sizeof(ctrlFd), 0, sizeof(ctrlFd));
285         (void)memset_s(dataFd, sizeof(dataFd), 0, sizeof(dataFd));
286         (void)memset_s(&childLoop, sizeof(childLoop), 0, sizeof(childLoop));
287         (void)memset_s(dataPipe, sizeof(dataPipe), 0, sizeof(dataPipe));
288         (void)memset_s(&hChildWorkTCP, sizeof(hChildWorkTCP), 0, sizeof(hChildWorkTCP));
289         (void)memset_s(&fdChildWorkTCP, sizeof(fdChildWorkTCP), 0, sizeof(fdChildWorkTCP));
290         (void)memset_s(&stat, sizeof(stat), 0, sizeof(stat));
291 #ifdef HDC_SUPPORT_UART
292         hUART = nullptr;
293 #endif
294         verifyType = AuthVerifyType::RSA_3072_SHA512;
295         isNeedDropData = true;
296         isSoftReset = false;
297     }
298 
~HdcSessionHdcSession299     ~HdcSession()
300     {
301         if (mapTask) {
302             delete mapTask;
303             mapTask = nullptr;
304         }
305         if (listKey) {
306             delete listKey;
307             listKey = nullptr;
308         }
309     }
310 };
311 using HSession = struct HdcSession *;
312 
313 enum class RemoteType {
314     REMOTE_NONE = 0,
315     REMOTE_FILE = 1,
316     REMOTE_APP = 2,
317 };
318 
319 struct HdcChannel {
320     void *clsChannel;  // ptr Class of serverForClient or client
321     uint32_t channelId;
322     std::string connectKey;
323     uv_tcp_t hWorkTCP;  // work channel for client, forward channel for server
324     uv_thread_t hWorkThread;
325     uint8_t uvHandleRef = 0;  // libuv handle ref -- just main thread now
326     bool handshakeOK;
327     bool isDead;
328     bool serverOrClient;  // client's channel/ server's channel
329     bool childCleared;
330     bool interactiveShellMode;  // Is shell interactive mode
331     bool keepAlive;             // channel will not auto-close by server
332     std::atomic<uint32_t> ref;
333     uint32_t targetSessionId;
334     // child work
335     uv_tcp_t hChildWorkTCP;  // work channel for server, no use in client
336     uv_os_sock_t fdChildWorkTCP;
337     // read io cache
338     int bufSize;         // total buffer size
339     int availTailIndex;  // buffer available data size
340     uint8_t *ioBuf;
341     // std
342     uv_tty_t stdinTty;
343     uv_tty_t stdoutTty;
344     char bufStd[128];
345     bool isCheck = false;
346     std::string key;
347     RemoteType remote = RemoteType::REMOTE_NONE;
348     bool fromClient = false;
349     bool connectLocalDevice = false;
350     bool isStableBuf = false;
351 };
352 using HChannel = struct HdcChannel *;
353 
354 struct HdcDaemonInformation {
355     uint8_t connType;
356     uint8_t connStatus;
357     std::string connectKey;
358     std::string usbMountPoint;
359     std::string devName;
360     HSession hSession;
361     std::string version;
362     std::string emgmsg;
363     std::string daemonAuthStatus;
364 };
365 using HDaemonInfo = struct HdcDaemonInformation *;
366 
367 struct HdcForwardInformation {
368     std::string taskString;
369     bool forwardDirection;  // true for forward, false is reverse;
370     uint32_t sessionId;
371     uint32_t channelId;
372     std::string connectKey;
373 };
374 using HForwardInfo = struct HdcForwardInformation *;
375 
376 struct HdcSessionInfo {
377     uint32_t sessionId = 0;
378     HSession hSession = nullptr;
379 
380     // class ptr
381     void *classInstance = nullptr;  //  HdcSessionBase instance, HdcServer or HdcDaemon
382     void *classModule = nullptr;    //  Communicate module, TCP or USB instance,HdcDaemonUSB HdcDaemonTCP etc...
383 };
384 using HSessionInfo = struct HdcSessionInfo *;
385 }
386 #endif
387