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 ¤tOffset); 199 struct libusb_config_descriptor* FindConfigDescriptorById(libusb_device *dev, uint8_t descId); 200 void ProcessExtraData(std::vector<uint8_t> &descriptor, size_t ¤tOffset, 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 ¤tConfig); 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