• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 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 
16 #ifndef OHOS_LIBUSB_ADAPTER_H
17 #define OHOS_LIBUSB_ADAPTER_H
18 
19 #include <memory>
20 #include <mutex>
21 #include <thread>
22 #include <list>
23 
24 #include <libusb.h>
25 
26 #include "libusb_sa_subscriber.h"
27 #include "v1_2/iusb_interface.h"
28 #include "v2_0/iusb_host_interface.h"
29 
30 namespace OHOS {
31 namespace HDI {
32 namespace Usb {
33 namespace V1_2 {
34 struct SyncTranfer {
35     int length;
36     int *transferred;
37     unsigned int timeout;
38 };
39 struct SendRequestAshmemParameter {
40     int32_t ashmemFd;
41     uint32_t ashmemSize;
42 };
43 
44 struct LibusbAsyncTransfer {
LibusbAsyncTransferLibusbAsyncTransfer45     explicit LibusbAsyncTransfer(uint32_t numOfIsoPackage)
46     {
47         transferRef = libusb_alloc_transfer(numOfIsoPackage);
48         ashmemRef = nullptr;
49     }
50 
~LibusbAsyncTransferLibusbAsyncTransfer51     ~LibusbAsyncTransfer()
52     {
53         if (transferRef != nullptr) {
54             libusb_free_transfer(transferRef);
55             transferRef = nullptr;
56         }
57         ashmemRef = nullptr;
58         cbRef = nullptr;
59     }
60 
61     libusb_transfer *transferRef;
62     sptr<Ashmem> ashmemRef;
63     sptr<V1_2::IUsbdTransferCallback> cbRef = nullptr;
64     int32_t busNum = 0;
65     int32_t devAddr = 0;
66     uint64_t userData = 0;
67 };
68 
69 struct LibusbAsyncWrapper {
70     std::list<LibusbAsyncTransfer *> transferList;
71     std::mutex transferLock;
72 };
73 
74 struct LibusbAsyncManager {
75     std::vector<std::pair<UsbDev, LibusbAsyncWrapper*>> transferVec;
76     std::mutex transferVecLock;
77 };
78 
79 struct DeviceInfo {
80     uint64_t deviceId;
81     uint16_t vendorId;
82 };
83 
84 struct LibusbBulkTransfer {
LibusbBulkTransferLibusbBulkTransfer85     explicit LibusbBulkTransfer()
86     {
87         bulkTransferRef = libusb_alloc_transfer(0);
88         buikAshmemRef = nullptr;
89         bulkCbRef = nullptr;
90     }
91 
~LibusbBulkTransferLibusbBulkTransfer92     ~LibusbBulkTransfer()
93     {
94         if (bulkTransferRef != nullptr) {
95             libusb_free_transfer(bulkTransferRef);
96             bulkTransferRef = nullptr;
97         }
98         buikAshmemRef = nullptr;
99         bulkCbRef = nullptr;
100     }
101 
102     libusb_transfer *bulkTransferRef;
103     sptr<Ashmem> buikAshmemRef;
104     sptr<V2_0::IUsbdBulkCallback> bulkCbRef;
105     int32_t busNum;
106     int32_t devAddr;
107     bool isTransferring {false};
108 };
109 
110 struct LibusbBulkWrapper {
111     std::list<LibusbBulkTransfer *> bulkTransferList;
112     std::mutex bulkTransferLock;
113 };
114 
115 struct LibusbBulkManager {
116     std::vector<std::pair<UsbDev, LibusbBulkWrapper*>> bulktransferVec;
117     std::mutex bulkTransferVecLock;
118 };
119 
120 class LibusbAdapter {
121 public:
122     LibusbAdapter();
123     ~LibusbAdapter();
124     int32_t OpenDevice(const UsbDev &dev);
125     int32_t CloseDevice(const UsbDev &dev);
126     int32_t ResetDevice(const UsbDev &dev);
127     int32_t GetDeviceDescriptor(const UsbDev &dev, std::vector<uint8_t> &descriptor);
128     int32_t GetDeviceFileDescriptor(const UsbDev &dev, int32_t &fd);
129     int32_t SetConfig(const UsbDev &dev, uint8_t configIndex);
130     int32_t GetConfig(const UsbDev &dev, uint8_t &configIndex);
131     int32_t ManageInterface(const UsbDev &dev, uint8_t interfaceId, bool disable);
132     int32_t BulkTransferRead(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, std::vector<uint8_t> &data);
133     int32_t BulkTransferReadwithLength(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, int32_t length,
134         std::vector<uint8_t> &data);
135     int32_t BulkTransferWrite(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout,
136         const std::vector<uint8_t> &data);
137     int32_t IsoTransferRead(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, std::vector<uint8_t> &data);
138     int32_t IsoTransferWrite(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout,
139         const std::vector<uint8_t> &data);
140     int32_t GetConfigDescriptor(const UsbDev &dev, uint8_t descId, std::vector<uint8_t> &descriptor);
141     int32_t ReleaseInterface(const UsbDev &dev, uint8_t interfaceId);
142     int32_t SetInterface(const UsbDev &dev, uint8_t interfaceId, uint8_t altIndex);
143     int32_t ClearHalt(const UsbDev &dev, const UsbPipe &pipe);
144     int32_t InterruptTransferRead(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, std::vector<uint8_t> &data);
145     int32_t InterruptTransferWrite(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout,
146         const std::vector<uint8_t> &data);
147     int32_t GetStringDescriptor(const UsbDev &dev, uint8_t descId, std::vector<uint8_t> &descriptor);
148     int32_t ClaimInterface(const UsbDev &dev, uint8_t interfaceId, uint8_t force);
149     int32_t ControlTransferRead(const UsbDev &dev, const UsbCtrlTransfer &ctrl, std::vector<uint8_t> &data);
150     int32_t ControlTransferWrite(const UsbDev &dev, const UsbCtrlTransfer &ctrl, const std::vector<uint8_t> &data);
151     int32_t ControlTransferReadwithLength(const UsbDev &dev, const UsbCtrlTransferParams &ctrlParams,
152         std::vector<uint8_t> &data);
153     int32_t GetFileDescriptor(const UsbDev &dev, int32_t &fd);
154     int32_t GetDeviceSpeed(const UsbDev &dev, uint8_t &speed);
155     int32_t GetInterfaceActiveStatus(const UsbDev &dev, uint8_t interfaceId, bool &unactivated);
156     int32_t SendPipeRequestWithAshmem(const UsbDev &dev, unsigned char endpointAddr,
157         SendRequestAshmemParameter sendRequestAshmemParameter, uint32_t &transferredLength, unsigned int timeout);
158     int32_t SendPipeRequest(const UsbDev &dev, unsigned char endpointAddr, uint32_t size,
159         uint32_t &transferedLength, unsigned int timeout);
160     int32_t GetRawDescriptor(const UsbDev &dev, std::vector<uint8_t> &descriptor);
161     int32_t GetCurrentInterfaceSetting(const UsbDev &dev, uint8_t &settingIndex);
162     int32_t GetDeviceMemMapFd(const UsbDev &dev, int &fd);
163     int32_t SetSubscriber(sptr<V2_0::IUsbdSubscriber> subscriber);
164     int32_t RemoveSubscriber(sptr<V2_0::IUsbdSubscriber> subscriber);
165 
166     /* Async Transfer */
167     int32_t AsyncSubmitTransfer(const UsbDev &dev, const V1_2::USBTransferInfo &info,
168         const sptr<V1_2::IUsbdTransferCallback> &cb, const sptr<Ashmem> &ashmem);
169     int32_t AsyncCancelTransfer(const UsbDev &dev, const int32_t endpoint);
170     int32_t GetDevices(std::vector<struct DeviceInfo> &devices);
171 
172     /* Bulk Transfer */
173     int32_t BulkRead(const UsbDev &dev, const UsbPipe &pipe, const sptr<Ashmem> &ashmem);
174     int32_t BulkWrite(const UsbDev &dev, const UsbPipe &pipe, const sptr<Ashmem> &ashmem);
175     int32_t BulkCancel(const UsbDev &dev, const UsbPipe &pipe);
176     int32_t RegBulkCallback(const UsbDev &dev, const UsbPipe &pipe, const sptr<V2_0::IUsbdBulkCallback> &cb);
177     int32_t UnRegBulkCallback(const UsbDev &dev, const UsbPipe &pipe);
178 
179     int32_t SetLoadUsbSaSubscriber(sptr<V1_2::LibUsbSaSubscriber> libUsbSaSubscriber);
180     static std::shared_ptr<LibusbAdapter> GetInstance();
181 
182 private:
183     int32_t LibUSBInit();
184     void LibUSBExit();
185     void GetCurrentDeviceList(libusb_context *ctx, sptr<V2_0::IUsbdSubscriber> subscriber);
186     void GetCurrentDevList(libusb_context *ctx, sptr<V1_2::LibUsbSaSubscriber> libUsbSaSubscriber);
187     int32_t GetUsbDevice(const UsbDev &dev, libusb_device **device);
188     int32_t FindHandleByDev(const UsbDev &dev, libusb_device_handle **handle);
189     void DeleteSettingsMap(libusb_device_handle* handle);
190     int32_t DoControlTransfer(const UsbDev &dev, const UsbCtrlTransfer &ctrl, std::vector<uint8_t> &data);
191     int32_t ReadDescriptors(int32_t fd, void **descriptors, size_t &descriptorsLength);
192     int32_t GetUsbDevicePath(const UsbDev &dev, char *pathBuf, size_t length);
193     void *AdapterRealloc(void *ptr, size_t oldSize, size_t newSize);
194     void *AllocateUsbDescriptorsMemory(size_t size);
195     void FreeUsbDescriptorsMemory(void *mem);
196     int32_t GetConfigDescriptor(libusb_device *dev, uint8_t descId, std::vector<uint8_t> &descriptor);
197     int32_t ProcessInterfaceDescriptors(const libusb_interface *iface, std::vector<uint8_t> &descriptor,
198         size_t &currentOffset);
199     struct libusb_config_descriptor* FindConfigDescriptorById(libusb_device *dev, uint8_t descId);
200     void ProcessExtraData(std::vector<uint8_t> &descriptor, size_t &currentOffset, const unsigned char *extra,
201         int32_t extraLength);
202     int32_t GetEndpointDesc(const UsbDev &dev, const UsbPipe &pipe, libusb_endpoint_descriptor **endpoint_desc,
203         libusb_device_handle** deviceHandle);
204     int32_t DoSyncPipeTranfer(libusb_device_handle *dev_handle, unsigned char endpoint,
205         unsigned char *buffer, SyncTranfer &syncTranfer);
206     unsigned char *GetMmapBufferByFd(int32_t fd, size_t len);
207     unsigned char *GetMmapFdAndBuffer(uint8_t busNumber, uint8_t busAddress, int32_t &fd, size_t len);
208     int32_t CloseMmapBuffer(void *mmapBuf, size_t length);
209     bool CheckDeviceAndConfiguration(libusb_device_handle *handle);
210     int32_t GetCurrentConfiguration(libusb_device_handle *handle, int32_t &currentConfig);
211     int32_t RemoveInterfaceFromMap(const UsbDev &dev, libusb_device_handle *devHandle, uint8_t interfaceId);
212     bool IsInterfaceIdByUsbDev(const UsbDev &dev, const uint8_t intfId);
213 
214     /* Async Transfer */
215     void TransferInit(const UsbDev &dev);
216     void TransferRelease(const UsbDev &dev);
217     uint8_t *AllocAsyncBuffer(const V1_2::USBTransferInfo &info, const sptr<Ashmem> &ashmem);
218     LibusbAsyncTransfer *CreateAsyncTransfer(const UsbDev &dev, const V1_2::USBTransferInfo &info,
219         const sptr<Ashmem> &ashmem, const sptr<V1_2::IUsbdTransferCallback> &cb);
220     int32_t FillAndSubmitTransfer(LibusbAsyncTransfer *asyncTransfer, libusb_device_handle *devHandle,
221         unsigned char *buffer, const V1_2::USBTransferInfo &info);
222     void DeleteAsyncDevRequest(const UsbDev &dev);
223     void ClearAsyncTranfer(LibusbAsyncWrapper *asyncWrapper);
224     void LibusbEventHandling();
225     static LibusbAsyncWrapper *GetAsyncWrapper(const UsbDev &dev);
226     static void HandleAsyncFailure(struct libusb_transfer *transfer);
227     static void AddTransferToList(LibusbAsyncTransfer *asyncTransfer);
228     static void DeleteTransferFromList(LibusbAsyncTransfer *asyncTransfer);
229     static void FeedbackToBase(struct libusb_transfer *transfer);
230     static void ParseIsoPacketDesc(libusb_transfer *transfer, std::vector<V1_2::UsbIsoPacketDescriptor> &isoPkgDescs);
231     static int32_t ReadAshmem(const sptr<Ashmem> &ashmem, int32_t length, uint8_t *buffer);
232     static int32_t WriteAshmem(const sptr<Ashmem> &ashmem, int32_t length, uint8_t *buffer);
233     static void LIBUSB_CALL HandleAsyncResult(struct libusb_transfer *transfer);
234 
235     /* Bulk Transfer */
236     static int32_t BulkReadAshmem(const sptr<Ashmem> &ashmem, int32_t length, uint8_t *buffer);
237     static int32_t BulkWriteAshmem(const sptr<Ashmem> &ashmem, int32_t length, uint8_t *buffer);
238     uint8_t *AllocBulkBuffer(const UsbPipe &pipe, const int32_t &length, const sptr<Ashmem> &ashmem);
239     static void DeleteBulkTransferFromList(LibusbBulkTransfer *bulkTransfer);
240     static void HandleBulkFail(struct libusb_transfer *transfer);
241     static void BulkFeedbackToBase(struct libusb_transfer *transfer);
242     static void LIBUSB_CALL HandleBulkResult(struct libusb_transfer *transfer);
243     void BulkTransferInit(const UsbDev &dev);
244     void BulkTransferRelease(const UsbDev &dev);
245     void DeleteBulkDevRequest(const UsbDev &dev);
246     void ClearBulkTranfer(LibusbBulkWrapper *bulkWrapper);
247     static LibusbBulkWrapper *GetBulkWrapper(const UsbDev &dev);
248     LibusbBulkTransfer *FindBulkTransfer(const UsbDev &dev, const UsbPipe &pipe, const sptr<Ashmem> &ashmem);
249 
250     static int HotplugCallback(libusb_context* ctx, libusb_device* device,
251         libusb_hotplug_event event, void* user_data);
252     static int LoadUsbSaCallback(libusb_context* ctx, libusb_device* device,
253         libusb_hotplug_event event, void* user_data);
254 private:
255     std::atomic<bool> isRunning;
256     std::thread eventThread;
257     libusb_hotplug_callback_handle hotplug_handle_;
258     static std::list<sptr<V2_0::IUsbdSubscriber>> subscribers_;
259     static sptr<V1_2::LibUsbSaSubscriber> libUsbSaSubscriber_;
260 };
261 } // namespace V1_2
262 } // namespace Usb
263 } // namespace HDI
264 } // namespace OHOS
265 #endif // OHOS_LIBUSB_ADAPTER_H
266