• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 HDC_HOST_USB_H
16 #define HDC_HOST_USB_H
17 
18 #include <memory>
19 #include <libusb.h>
20 #include "ctimer.h"
21 #include <map>
22 #include <vector>
23 #include <mutex>
24 #include <condition_variable>
25 #include "securec.h"
26 #include "ffi_utils.h"
27 
28 namespace Hdc {
29 using namespace std;
30 constexpr uint16_t MAX_USBFFS_BULK = 62464;
31 constexpr uint16_t MAX_USBFFS_BULK2 = 63488;
32 enum ConnType { CONN_USB = 0, CONN_TCP, CONN_SERIAL, CONN_BT };
33 enum ConnStatus { STATUS_UNKNOW = 0, STATUS_READY, STATUS_CONNECTED, STATUS_OFFLINE };
34 
35 enum OperateID {
36     OP_ADD,
37     OP_REMOVE,
38     OP_QUERY,
39     OP_QUERY_REF,  // crossthread query, manually reduce ref
40     OP_GET_STRLIST,
41     OP_GET_STRLIST_FULL,
42     OP_GET_READY_STRLIST,
43     OP_GET_ANY,
44     OP_UPDATE,
45     OP_CLEAR,
46     OP_INIT,
47     OP_GET_ONLY,
48     OP_VOTE_RESET,
49     OP_WAIT_FOR_ANY
50 };
51 struct PersistBuffer {
52     char *ptr;
53     uint64_t size;
54 };
55 struct HdcDaemonInformation {
56     uint8_t connType;
57     uint8_t connStatus;
58     std::string connectKey;
59     std::string usbMountPoint;
60     std::string devName;
61     std::string version;
62 };
63 using HDaemonInfo = struct HdcDaemonInformation *;
64 struct HostUSBEndpoint {
HostUSBEndpointHostUSBEndpoint65     explicit HostUSBEndpoint(uint16_t epBufSize)
66     {
67         endpoint = 0;
68         sizeEpBuf = epBufSize;  // MAX_USBFFS_BULK
69         transfer = libusb_alloc_transfer(0);
70         isShutdown = true;
71         isComplete = true;
72         bulkInOut = false;
73         buf = new (std::nothrow) uint8_t[sizeEpBuf];
74         (void)memset_s(buf, sizeEpBuf, 0, sizeEpBuf);
75     }
~HostUSBEndpointHostUSBEndpoint76     ~HostUSBEndpoint()
77     {
78         libusb_free_transfer(transfer);
79         delete[] buf;
80     }
81     uint8_t endpoint;
82     uint8_t *buf;  // MAX_USBFFS_BULK
83     bool isComplete;
84     bool isShutdown;
85     bool bulkInOut;  // true is bulkIn
86     uint16_t sizeEpBuf;
87     std::mutex mutexIo;
88     std::mutex mutexCb;
89     condition_variable cv;
90     libusb_transfer *transfer;
91 };
92 
93 struct HdcUSB {
94     libusb_context *ctxUSB = nullptr;  // child-use, main null
95     libusb_device *device;
96     libusb_device_handle *devHandle;
97     uint16_t retryCount;
98     uint8_t devId;
99     uint8_t busId;
100     uint8_t interfaceNumber;
101     std::string serialNumber;
102     std::string usbMountPoint;
103     HostUSBEndpoint hostBulkIn;
104     HostUSBEndpoint hostBulkOut;
HdcUSBHdcUSB105     HdcUSB() : hostBulkIn(MAX_USBFFS_BULK2), hostBulkOut(MAX_USBFFS_BULK) {}
106 
107     uint32_t payloadSize;
108     uint16_t wMaxPacketSizeSend;
109     bool resetIO;  // if true, must break write and read,default false
110     std::mutex lockDeviceHandle;
111     std::mutex lockSendUsbBlock;
112 };
113 using HUSB = struct HdcUSB *;
114 
115 enum UsbCheckStatus {
116     HOST_USB_IGNORE = 1,
117     HOST_USB_READY,
118     HOST_USB_REGISTER,
119 };
120 
121 class HostUsb {
122 public:
123     HostUsb();
124     ~HostUsb();
125     int Initial();
126     void Stop();
127     static void UsbWorkThread(void *arg);  // 3rd thread
128     static void WatchUsbNodeChange(void *arg);
129     static void LIBUSB_CALL USBBulkCallback(struct libusb_transfer *transfer);
130     void CancelUsbIo(HUSB hUsb);
131     PersistBuffer ReadUsbIO(HUSB hUsb, int exceptedSize);
132     int WriteUsbIO(HUSB hUsb, SerializedBuffer buf);
133     HUSB GetUsbDevice(std::string connectKey);
134     string AdminDaemonMap(uint8_t opType, const string &connectKey, HDaemonInfo &hDaemonInfoInOut);
135     void UpdateUSBDaemonInfo(HUSB hUSB, uint8_t connStatus);
136 private:
137     bool DetectMyNeed(libusb_device *device, string &sn);
138     void ReviewUsbNodeLater(string &nodeKey);
139     void RemoveIgnoreDevice(string &mountInfo);
140     void CheckUsbEndpoint(int& ret, HUSB hUSB, libusb_config_descriptor *descConfig);
141 #ifdef HOST_MAC
142     int CheckActiveConfig(libusb_device *device, HUSB hUSB, libusb_device_descriptor& desc);
143 #else
144     int CheckActiveConfig(libusb_device *device, HUSB hUSB);
145 #endif
146     int OpenDeviceMyNeed(HUSB hUSB);
147     bool HasValidDevice(libusb_device *device);
148     int CheckDescriptor(HUSB hUSB, libusb_device_descriptor& desc);
149     bool IsDebuggableDev(const struct libusb_interface_descriptor *ifDescriptor);
150     bool FindDeviceByID(HUSB hUSB, const char *usbMountPoint, libusb_context *ctxUSB);
151     string GetDaemonMapList(uint8_t opType);
152 
153     libusb_context *ctxUSB;
154     bool running;
155     std::map<string, UsbCheckStatus> mapIgnoreDevice;
156     std::unique_ptr<CTimer> timer;
157     std::map<string, HUSB> mapUsbDevice;
158     std::mutex lockMapDaemon;
159     map<string, HDaemonInfo> mapDaemon;
160 };
161 }
162 #endif
163