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