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