1diff --git a/backend/usb_manager.cxx b/backend/usb_manager.cxx 2new file mode 100644 3index 0000000..baf329a 4--- /dev/null 5+++ b/backend/usb_manager.cxx 6@@ -0,0 +1,683 @@ 7+/* 8+ * Copyright (c) 2024 Huawei Device Co., Ltd. 9+ * Licensed under the Apache License, Version 2.0 (the "License"); 10+ * you may not use this file except in compliance with the License. 11+ * You may obtain a copy of the License at 12+ * 13+ * http://www.apache.org/licenses/LICENSE-2.0 14+ * 15+ * Unless required by applicable law or agreed to in writing, software 16+ * distributed under the License is distributed on an "AS IS" BASIS, 17+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18+ * See the License for the specific language governing permissions and 19+ * limitations under the License. 20+ */ 21+ 22+/* 23+ * OH USB interface code for CUPS. 24+ */ 25+ 26+/* 27+ * Include necessary headers. 28+ */ 29+ 30+#include "usb_manager.h" 31+#include "usb_srv_client.h" 32+#include "v1_0/iusb_interface.h" 33+ 34+#include <map> 35+#include <regex> 36+#include <string> 37+#include <thread> 38+#include <securec.h> 39+ 40+using namespace std; 41+using namespace OHOS; 42+using namespace OHOS::USB; 43+ 44+#define SAFE_DELETE(ptr) \ 45+ if ((ptr) != nullptr) { \ 46+ delete (ptr); \ 47+ (ptr) = nullptr; \ 48+ } 49+ 50+#define SAFE_DELETE_ARRAY(ptr) \ 51+ if ((ptr) != nullptr) { \ 52+ delete[] (ptr); \ 53+ (ptr) = nullptr; \ 54+ } 55+ 56+int32_t BulkTransferWriteData( 57+ USBDevicePipe &usbDevicePipe, USBEndpoint &endpoint, const std::string &sendDataStr, int32_t timeout); 58+int32_t ParseDeviceDescriptor(UsbDevice &usbDevice, ohusb_device_descriptor *devDesc); 59+int32_t ParseConfigDescriptor(USBConfig &usbConfig, ohusb_config_descriptor *confDesc); 60+int32_t ParseInterface(std::vector<UsbInterface> &usbIfaces, ohusb_interface *usbInterface, int32_t ifaceIndex); 61+int32_t ParseInterfaceDescriptor(UsbInterface &usbInterface, ohusb_interface_descriptor *ifaceDesc); 62+int32_t ParseEndpointDescriptor(USBEndpoint &usbEndpoint, ohusb_endpoint_descriptor *epDesc); 63+void ReleaseDeviceDescriptor(ohusb_device_descriptor *devDesc); 64+void ReleaseConfigDescriptor(ohusb_config_descriptor *confDesc); 65+void ReleaseInterface(ohusb_interface *iface); 66+void ReleaseInterfaceDescriptor(ohusb_interface_descriptor *ifaceDesc); 67+void DumpDeviceDescriptor(ohusb_device_descriptor *devdesc); 68+void DumpConfigDescriptor(ohusb_config_descriptor *confDesc); 69+void DumpInterfaceDescriptor(ohusb_interface_descriptor *ifaceDesc); 70+void DumpEndpointDescriptor(ohusb_endpoint_descriptor *eptDesc); 71+char *CopyString(const std::string &source); 72+ 73+int32_t OH_GetDevices(ohusb_device_descriptor** list, ssize_t *numdevs) 74+{ 75+ fprintf(stderr, "DEBUG: OH_GetDevices enter\n"); 76+ vector<UsbDevice> devlist; 77+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance(); 78+ auto getDevRet = usbSrvClient.GetDevices(devlist); 79+ fprintf(stderr, "DEBUG: OH_GetDevices getDevRet = %d\n", getDevRet); 80+ if (getDevRet != OHOS::ERR_OK) { 81+ return OHUSB_ERROR_IO; 82+ } 83+ if (devlist.empty()) { 84+ return OHUSB_SUCCESS; 85+ } 86+ ssize_t devCount = devlist.size(); 87+ *numdevs = 0; 88+ fprintf(stderr, "DEBUG: OH_GetDevices device nums = %zd\n", devCount); 89+ 90+ *list = (ohusb_device_descriptor *)calloc((size_t)devCount, sizeof(ohusb_device_descriptor)); 91+ if (*list == nullptr) { 92+ fprintf(stderr, "DEBUG: OH_GetDevices list is nullptr\n"); 93+ return OHUSB_ERROR_NO_MEM; 94+ } 95+ for (ssize_t i = 0; i < devCount; i++) { 96+ fprintf(stderr, "DEBUG: OH_GetDevices devlist[%zd] devAddr = %d, busNum = %d\n", 97+ i, devlist[i].GetDevAddr(), devlist[i].GetBusNum()); 98+ if (ParseDeviceDescriptor(devlist[i], *list + i) != OHUSB_SUCCESS) { 99+ return OHUSB_ERROR_IO; 100+ } 101+ (*numdevs)++; 102+ } 103+ return OHUSB_SUCCESS; 104+} 105+ 106+int32_t OH_OpenDevice(ohusb_device_descriptor *devDesc, ohusb_pipe **pipe) 107+{ 108+ fprintf(stderr, "DEBUG: OH_OpenDevice enter\n"); 109+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance(); 110+ UsbDevice usbDevice; 111+ usbDevice.SetBusNum(devDesc->busNum); 112+ usbDevice.SetDevAddr(devDesc->devAddr); 113+ USBDevicePipe usbDevicePipe; 114+ auto openDevRet = usbSrvClient.OpenDevice(usbDevice, usbDevicePipe); 115+ fprintf(stderr, "DEBUG: OH_OpenDevice getDevRet = %d\n", openDevRet); 116+ if (openDevRet != OHOS::ERR_OK) { 117+ return OHUSB_ERROR_IO; 118+ } 119+ *pipe = (ohusb_pipe *)calloc(1, sizeof(ohusb_pipe)); 120+ if (*pipe == nullptr) { 121+ fprintf(stderr, "DEBUG: OH_OpenDevice pipe is nullptr\n"); 122+ return OHUSB_ERROR_NO_MEM; 123+ } 124+ (*pipe)->busNum = usbDevicePipe.GetBusNum(); 125+ (*pipe)->devAddr = usbDevicePipe.GetDevAddr(); 126+ fprintf(stderr, "DEBUG: OH_OpenDevice busNum=%d, devAddr=%d\n", (*pipe)->busNum, (*pipe)->devAddr); 127+ fprintf(stderr, "DEBUG: OH_OpenDevice out\n"); 128+ return OHUSB_SUCCESS; 129+} 130+ 131+int32_t OH_CloseDevice(ohusb_pipe *pipe) 132+{ 133+ fprintf(stderr, "DEBUG: OH_CloseDevice enter\n"); 134+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance(); 135+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr}; 136+ int32_t ret = usbSrvClient.Close(usbDevicePipe); 137+ if (ret != ERR_OK) { 138+ fprintf(stderr, "DEBUG: OH_CloseDevice fail with ret = %d\n", ret); 139+ return OHUSB_ERROR_BUSY; 140+ } 141+ fprintf(stderr, "DEBUG: OH_CloseDevice out\n"); 142+ return OHUSB_SUCCESS; 143+} 144+ 145+int32_t OH_ClaimInterface(ohusb_pipe *pipe, int interfaceId, bool force) 146+{ 147+ fprintf(stderr, "DEBUG: OH_ClaimInterface enter\n"); 148+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance(); 149+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr}; 150+ UsbInterface usbInterface; 151+ usbInterface.SetId(interfaceId); 152+ int32_t ret = usbSrvClient.ClaimInterface(usbDevicePipe, usbInterface, force); 153+ if (ret != ERR_OK) { 154+ fprintf(stderr, "DEBUG: OH_ClaimInterface fail with ret = %d\n", ret); 155+ return OHUSB_ERROR_BUSY; 156+ } 157+ fprintf(stderr, "DEBUG: OH_ClaimInterface out\n"); 158+ return OHUSB_SUCCESS; 159+} 160+ 161+int32_t OH_ReleaseInterface(ohusb_pipe *pipe, int interfaceId) 162+{ 163+ fprintf(stderr, "DEBUG: OH_ReleaseInterface enter\n"); 164+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance(); 165+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr}; 166+ UsbInterface usbInterface; 167+ usbInterface.SetId(interfaceId); 168+ int32_t ret = usbSrvClient.ReleaseInterface(usbDevicePipe, usbInterface); 169+ if (ret != ERR_OK) { 170+ fprintf(stderr, "DEBUG: OH_ReleaseInterface fail with ret = %d\n", ret); 171+ return OHUSB_ERROR_BUSY; 172+ } 173+ fprintf(stderr, "DEBUG: OH_ReleaseInterface out\n"); 174+ return OHUSB_SUCCESS; 175+} 176+ 177+int32_t OH_BulkTransferRead( 178+ ohusb_pipe *pipe, ohusb_transfer_pipe *tpipe, unsigned char *data, int length, int *transferred) 179+{ 180+ fprintf(stderr, "DEBUG: OH_BulkTransferRead enter\n"); 181+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance(); 182+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr}; 183+ USBEndpoint endpoint; 184+ endpoint.SetInterfaceId(tpipe->bInterfaceId); 185+ endpoint.SetAddr(tpipe->bEndpointAddress); 186+ std::vector<uint8_t> readTempBuffer; 187+ size_t readSize = 0; 188+ int32_t ret = usbSrvClient.BulkTransfer(usbDevicePipe, endpoint, readTempBuffer, OHUSB_BULKTRANSFER_READ_TIMEOUT); 189+ fprintf(stderr, "DEBUG: OH_BulkTransferRead ret = %d\n", ret); 190+ if (ret == HDF_DEV_ERR_NO_DEVICE) { 191+ fprintf(stderr, "DEBUG: OH_BulkTransferRead HDF_DEV_ERR_NO_DEVICE, The device module has no device\n"); 192+ return OHUSB_ERROR_NO_DEVICE; 193+ } 194+ readSize = readTempBuffer.size(); 195+ fprintf(stderr, "DEBUG: OH_BulkTransferRead readSize = %zu\n", readSize); 196+ if (ret == OHUSB_SUCCESS) { 197+ if (readSize < 512) { 198+ std::copy(readTempBuffer.begin(), readTempBuffer.begin() + readSize, data); 199+ *transferred = readSize; 200+ } 201+ return OHUSB_SUCCESS; 202+ } 203+ 204+ fprintf(stderr, "DEBUG: OH_BulkTransferRead read data time out\n"); 205+ return OHUSB_ERROR_TIMEOUT; 206+} 207+ 208+int32_t OH_BulkTransferWrite( 209+ ohusb_pipe *pipe, ohusb_transfer_pipe *tpipe, unsigned char *data, int length, int *transferred, int32_t timeout) 210+{ 211+ fprintf(stderr, "DEBUG: OH_BulkTransferRead enter\n"); 212+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr}; 213+ USBEndpoint endpoint; 214+ endpoint.SetInterfaceId(tpipe->bInterfaceId); 215+ endpoint.SetAddr(tpipe->bEndpointAddress); 216+ int32_t ret = 0; 217+ int leftDataLen = length; 218+ while (leftDataLen > 0) { 219+ fprintf(stderr, "DEBUG: OH_BulkTransferWrite leftDataLen waiting for transfer = %d\n", leftDataLen); 220+ size_t len = leftDataLen > OHUSB_ENDPOINT_MAX_LENGTH ? OHUSB_ENDPOINT_MAX_LENGTH : leftDataLen; 221+ std::string sendDataStr(reinterpret_cast<char *>(data), len); 222+ ret = BulkTransferWriteData(usbDevicePipe, endpoint, sendDataStr, timeout); 223+ if (ret == OHUSB_ERROR_IO) { 224+ fprintf(stderr, "DEBUG: OH_BulkTransferWrite OHUSB_ERROR_IO\n"); 225+ int32_t claimRet = OH_ClaimInterface(pipe, tpipe->bClaimedInterfaceId, true); 226+ if (claimRet >= 0) { 227+ fprintf(stderr, "DEBUG: OH_BulkTransferWrite OH_ClaimInterface success ret = %d\n", claimRet); 228+ continue; 229+ } 230+ } 231+ if (ret != 0) { 232+ return ret; 233+ } 234+ fprintf(stderr, "DEBUG: OH_BulkTransferWrite transferred data len = %zu\n", len); 235+ leftDataLen -= len; 236+ data += len; 237+ } 238+ *transferred = length - leftDataLen; 239+ fprintf(stderr, "DEBUG: transferred data len = %d\n", *transferred); 240+ fprintf(stderr, "DEBUG: OH_BulkTransferWrite out\n"); 241+ return OHUSB_SUCCESS; 242+} 243+ 244+int32_t BulkTransferWriteData( 245+ USBDevicePipe &usbDevicePipe, USBEndpoint &endpoint, const std::string &sendDataStr, int32_t timeout) 246+{ 247+ std::vector<uint8_t> vectorRequestBuffer; 248+ vectorRequestBuffer.assign(sendDataStr.begin(), sendDataStr.end()); 249+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance(); 250+ uint32_t retryNum = 0; 251+ int32_t ret = 0; 252+ do { 253+ fprintf(stderr, "DEBUG: BulkTransferWriteData write data retryCout: %d\n", retryNum); 254+ ret = usbSrvClient.BulkTransfer(usbDevicePipe, endpoint, vectorRequestBuffer, timeout); 255+ fprintf(stderr, "DEBUG: BulkTransferWrite ret: %d\n", ret); 256+ if (ret == HDF_DEV_ERR_NO_DEVICE) { 257+ fprintf(stderr, "DEBUG: BulkTransferWriteData no device\n"); 258+ return OHUSB_ERROR_NO_DEVICE; 259+ } 260+ if (ret == OHUSB_ERROR_IO) { 261+ fprintf(stderr, "DEBUG: BulkTransferWriteData OHUSB_ERROR_IO\n"); 262+ return OHUSB_ERROR_IO; 263+ } 264+ if (ret == OHUSB_ERROR_TIMEOUT) { 265+ std::this_thread::sleep_for(std::chrono::milliseconds(OHUSB_BULKTRANSFER_WRITE_SLEEP)); 266+ } 267+ retryNum++; 268+ } while (ret != OHUSB_SUCCESS && retryNum < OHUSB_WRITE_RETRY_MAX_TIMES); 269+ if (ret != 0) { 270+ fprintf(stderr, "DEBUG: Write data fail\n"); 271+ return ret; 272+ } 273+ return ret; 274+} 275+ 276+int32_t OH_ControlTransferRead( 277+ ohusb_pipe *pipe, ohusb_control_transfer_parameter *ctrlParam, unsigned char *data, uint16_t length) 278+{ 279+ fprintf(stderr, "DEBUG: OH_ControlTransferRead enter\n"); 280+ if (pipe == nullptr || ctrlParam == nullptr) { 281+ fprintf(stderr, "DEBUG: pipe or ctrlParam is nullptr\n"); 282+ return OHUSB_ERROR_IO; 283+ } 284+ fprintf(stderr, "DEBUG: OH_ControlTransferRead busNum=%d, devAddr=%d\n", pipe->busNum, pipe->devAddr); 285+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr}; 286+ int32_t requestType = ctrlParam->requestType; 287+ int32_t request = ctrlParam->request; 288+ int32_t value = ctrlParam->value; 289+ int32_t index = ctrlParam->index; 290+ int32_t timeOut = ctrlParam->timeout; 291+ const HDI::Usb::V1_0::UsbCtrlTransfer tctrl = {requestType, request, value, index, timeOut}; 292+ std::vector<uint8_t> bufferData(length, 0); 293+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance(); 294+ uint32_t retryNum = 0; 295+ int32_t ret = OHUSB_SUCCESS; 296+ do { 297+ ret = usbSrvClient.ControlTransfer(usbDevicePipe, tctrl, bufferData); 298+ retryNum++; 299+ } while ((ret != OHUSB_SUCCESS || bufferData.size() == 0) && retryNum < OHUSB_CONTROLTRANSFER_READ_RETRY_MAX_TIMES); 300+ fprintf(stderr, "DEBUG: OH_ControlTransferRead ret = %d, retryCount: %d\n", ret, retryNum); 301+ if (ret != 0) { 302+ fprintf(stderr, "DEBUG: OH_ControlTransferRead fail\n"); 303+ return OHUSB_ERROR_IO; 304+ } 305+ fprintf(stderr, "DEBUG: OH_ControlTransferRead bufferData size = %zu\n", bufferData.size()); 306+ 307+ if (bufferData.size() == 0) { 308+ return 0; 309+ } 310+ 311+ if ((value >> 8) == OHUSB_DT_STRING) { 312+ int bufferLen = bufferData.size(); 313+ uint16_t *wbuf = new (std::nothrow) uint16_t[bufferLen + 1](); 314+ if (wbuf == nullptr) { 315+ fprintf(stderr, "DEBUG: OH_ControlTransferRead wbuf is nullptr.\n"); 316+ return OHUSB_ERROR_NO_MEM; 317+ } 318+ for (uint32_t i = 0; i < bufferLen - 2; ++i) { 319+ wbuf[i] = bufferData[i + 2]; 320+ } 321+ std::wstring wstr(reinterpret_cast<wchar_t *>(wbuf), (bufferLen - 2) / 2); 322+ std::string buffer(wstr.begin(), wstr.end()); 323+ fprintf(stderr, "DEBUG: OH_ControlTransferRead buffer = %s\n", buffer.c_str()); 324+ if (memcpy_s(data, length, buffer.c_str(), buffer.length()) != 0) { 325+ fprintf(stderr, "DEBUG: OH_ControlTransferRead memcpy_s fail.\n"); 326+ return OHUSB_ERROR_NO_MEM; 327+ } 328+ } else if (memcpy_s(data, length, bufferData.data(), bufferData.size()) != 0) { 329+ fprintf(stderr, "DEBUG: OH_ControlTransferRead memcpy_s fail.\n"); 330+ return OHUSB_ERROR_NO_MEM; 331+ } 332+ 333+ fprintf(stderr, "DEBUG: OH_ControlTransferRead out\n"); 334+ return bufferData.size(); 335+} 336+ 337+int32_t OH_ControlTransferWrite( 338+ ohusb_pipe *pipe, ohusb_control_transfer_parameter *ctrlParam, unsigned char *data, uint16_t length) 339+{ 340+ fprintf(stderr, "DEBUG: OH_ControlTransferWrite enter\n"); 341+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr}; 342+ int32_t requestType = ctrlParam->requestType; 343+ int32_t request = ctrlParam->request; 344+ int32_t value = ctrlParam->value; 345+ int32_t index = ctrlParam->index; 346+ int32_t timeOut = ctrlParam->timeout; 347+ const HDI::Usb::V1_0::UsbCtrlTransfer tctrl = {requestType, request, value, index, timeOut}; 348+ std::vector<uint8_t> bufferData(length, 0); 349+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance(); 350+ int32_t ret = usbSrvClient.ControlTransfer(usbDevicePipe, tctrl, bufferData); 351+ if (ret != 0) { 352+ fprintf(stderr, "DEBUG: OH_ControlTransferWrite fail with ret = %d\n", ret); 353+ return OHUSB_ERROR_IO; 354+ } 355+ 356+ fprintf(stderr, "DEBUG: OH_ControlTransferWrite out\n"); 357+ return length; 358+} 359+ 360+int32_t OH_GetStringDescriptor(ohusb_pipe *pipe, int descId, unsigned char *descriptor, int length) 361+{ 362+ fprintf(stderr, "DEBUG: OH_GetStringDescriptor enter\n"); 363+ if (descId == 0) { 364+ return OHUSB_ERROR_INVALID_PARAM; 365+ } 366+ ohusb_control_transfer_parameter ctrlParam = { 367+ OHUSB_ENDPOINT_IN, 368+ OHUSB_REQUEST_GET_DESCRIPTOR, 369+ (uint16_t)((OHUSB_DT_STRING << 8) | descId), 370+ OHUSB_LANGUAGE_ID_ENGLISH, 371+ OHUSB_GET_STRING_DESCRIPTOR_TIMEOUT 372+ }; 373+ auto ret = OH_ControlTransferRead(pipe, &ctrlParam, descriptor, length); 374+ if (ret <= 0) { 375+ fprintf(stderr, "DEBUG: OH_GetStringDescriptor OH_ControlTransferRead failed\n"); 376+ return ret; 377+ } 378+ 379+ fprintf(stderr, "DEBUG: OH_GetStringDescriptor out\n"); 380+ return ret; 381+} 382+ 383+int32_t ParseDeviceDescriptor(UsbDevice &usbDevice, ohusb_device_descriptor *devDesc) 384+{ 385+ fprintf(stderr, "DEBUG: ParseDeviceDescriptor enter\n"); 386+ if (devDesc == nullptr) { 387+ fprintf(stderr, "DEBUG: ParseDeviceDescriptor devDesc is nullptr\n"); 388+ return OHUSB_ERROR_NO_MEM; 389+ } 390+ 391+ devDesc->devAddr = usbDevice.GetDevAddr(); 392+ devDesc->busNum = usbDevice.GetBusNum(); 393+ devDesc->bcdUSB = usbDevice.GetbcdUSB(); 394+ devDesc->bDeviceClass = usbDevice.GetClass(); 395+ devDesc->bDeviceSubClass = usbDevice.GetSubclass(); 396+ devDesc->bDeviceProtocol = usbDevice.GetProtocol(); 397+ devDesc->bMaxPacketSize0 = usbDevice.GetbMaxPacketSize0(); 398+ devDesc->idVendor = usbDevice.GetVendorId(); 399+ devDesc->idProduct = usbDevice.GetProductId(); 400+ devDesc->iManufacturer = usbDevice.GetiManufacturer(); 401+ devDesc->iProduct = usbDevice.GetiProduct(); 402+ devDesc->iSerialNumber = usbDevice.GetiSerialNumber(); 403+ devDesc->bNumConfigurations = 0; 404+ ohusb_config_descriptor *config = 405+ (ohusb_config_descriptor *)calloc((size_t)usbDevice.GetConfigCount(), sizeof(ohusb_config_descriptor)); 406+ if (config == nullptr) { 407+ fprintf(stderr, "DEBUG: ParseDeviceDescriptor config is null.\n"); 408+ return OHUSB_ERROR_NO_MEM; 409+ } 410+ devDesc->config = config; 411+ 412+ for (int i = 0; i < usbDevice.GetConfigCount(); i++) { 413+ USBConfig usbConfig; 414+ usbDevice.GetConfig(i, usbConfig); 415+ if (ParseConfigDescriptor(usbConfig, config + i) != OHUSB_SUCCESS) { 416+ return OHUSB_ERROR_IO; 417+ } 418+ (devDesc->bNumConfigurations)++; 419+ } 420+ DumpDeviceDescriptor(devDesc); 421+ fprintf(stderr, "DEBUG: ParseDeviceDescriptor out\n"); 422+ return OHUSB_SUCCESS; 423+} 424+ 425+int32_t ParseConfigDescriptor(USBConfig &usbConfig, ohusb_config_descriptor *confDesc) 426+{ 427+ fprintf(stderr, "DEBUG: ParseConfigDescriptor enter\n"); 428+ if (confDesc == nullptr) { 429+ fprintf(stderr, "DEBUG: ParseConfigDescriptor confDesc is nullptr\n"); 430+ return OHUSB_ERROR_NO_MEM; 431+ } 432+ confDesc->iConfiguration = usbConfig.GetId(); 433+ confDesc->bmAttributes = usbConfig.GetAttributes(); 434+ confDesc->MaxPower = usbConfig.GetMaxPower(); 435+ 436+ std::vector<UsbInterface> usbIfaces = usbConfig.GetInterfaces(); 437+ int32_t ifaceCount = usbIfaces.size() > 0 ? usbIfaces[usbIfaces.size() - 1].GetId() + 1 : 0; 438+ 439+ confDesc->bNumInterfaces = 0; 440+ ohusb_interface *usbInterface = 441+ (ohusb_interface *)calloc((size_t)ifaceCount, sizeof(ohusb_interface)); 442+ if (usbInterface == nullptr) { 443+ fprintf(stderr, "DEBUG: ParseConfigDescriptor usbInterface is nullptr\n"); 444+ return OHUSB_ERROR_NO_MEM; 445+ } 446+ confDesc->interface = usbInterface; 447+ for (int32_t ifaceIndex = 0; ifaceIndex < ifaceCount; ifaceIndex++) { 448+ if (ParseInterface(usbIfaces, usbInterface + ifaceIndex, ifaceIndex) != OHUSB_SUCCESS) { 449+ return OHUSB_ERROR_IO; 450+ } 451+ (confDesc->bNumInterfaces)++; 452+ } 453+ DumpConfigDescriptor(confDesc); 454+ fprintf(stderr, "DEBUG: ParseConfigDescriptor out\n"); 455+ return OHUSB_SUCCESS; 456+} 457+ 458+int32_t ParseInterface(std::vector<UsbInterface> &usbIfaces, ohusb_interface *usbInterface, int32_t ifaceIndex) 459+{ 460+ fprintf(stderr, "DEBUG: ParseInterface ifaceIndex=%d\n", ifaceIndex); 461+ for (int32_t usbIfacesIndex = 0; usbIfacesIndex < usbIfaces.size(); usbIfacesIndex++) { 462+ if (usbIfaces[usbIfacesIndex].GetId() == ifaceIndex) { 463+ ohusb_interface_descriptor *altsetting; 464+ altsetting = (ohusb_interface_descriptor *) 465+ calloc((size_t)(usbInterface->num_altsetting + 1), sizeof(*altsetting)); 466+ if (altsetting == nullptr) { 467+ fprintf(stderr, "DEBUG: ParseInterface altsetting is nullptr\n"); 468+ return OHUSB_ERROR_NO_MEM; 469+ } 470+ if (usbInterface->num_altsetting != 0 && 471+ memcpy_s(altsetting, sizeof(*altsetting) * (size_t)(usbInterface->num_altsetting), 472+ usbInterface->altsetting, sizeof(*altsetting) * (size_t)(usbInterface->num_altsetting)) != 0) { 473+ fprintf(stderr, "DEBUG: ParseInterface memcpy_s fail.\n"); 474+ return OHUSB_ERROR_NO_MEM; 475+ } 476+ usbInterface->altsetting = altsetting; 477+ if (ParseInterfaceDescriptor(usbIfaces[usbIfacesIndex], altsetting + (usbInterface->num_altsetting)) 478+ != OHUSB_SUCCESS) { 479+ return OHUSB_ERROR_IO; 480+ } 481+ usbInterface->num_altsetting++; 482+ } 483+ } 484+ fprintf(stderr, "DEBUG: ParseInterface num_altsetting=%d\n", usbInterface->num_altsetting); 485+ return OHUSB_SUCCESS; 486+} 487+ 488+int32_t ParseInterfaceDescriptor(UsbInterface &usbInterface, ohusb_interface_descriptor *ifaceDesc) 489+{ 490+ fprintf(stderr, "DEBUG: ParseInterfaceDescriptor enter\n"); 491+ if (ifaceDesc == nullptr) { 492+ fprintf(stderr, "DEBUG: ParseInterfaceDescriptor ifaceDesc is nullptr\n"); 493+ return OHUSB_ERROR_NO_MEM; 494+ } 495+ ifaceDesc->bInterfaceNumber = usbInterface.GetId(); 496+ ifaceDesc->bAlternateSetting = usbInterface.GetAlternateSetting(); 497+ ifaceDesc->bInterfaceClass = usbInterface.GetClass(); 498+ ifaceDesc->bInterfaceSubClass = usbInterface.GetSubClass(); 499+ ifaceDesc->bInterfaceProtocol = usbInterface.GetProtocol(); 500+ ifaceDesc->bNumEndpoints = 0; 501+ fprintf(stderr, "DEBUG: ParseInterfaceDescriptor class=%x, subclass=%x, protocol=%x.\n", 502+ usbInterface.GetClass(), usbInterface.GetSubClass(), usbInterface.GetProtocol()); 503+ ohusb_endpoint_descriptor *endpoint; 504+ endpoint = (ohusb_endpoint_descriptor *) 505+ calloc((size_t)usbInterface.GetEndpointCount(), sizeof(ohusb_endpoint_descriptor)); 506+ if (endpoint == nullptr) { 507+ fprintf(stderr, "DEBUG: endpoint is null.\n"); 508+ return OHUSB_ERROR_NO_MEM; 509+ } 510+ ifaceDesc->endpoint = endpoint; 511+ std::vector<USBEndpoint> endpoints = usbInterface.GetEndpoints(); 512+ for (int i = 0; i < usbInterface.GetEndpointCount(); i++) { 513+ if (ParseEndpointDescriptor(endpoints[i], endpoint + i) != OHUSB_SUCCESS) { 514+ return OHUSB_ERROR_IO; 515+ } 516+ (ifaceDesc->bNumEndpoints)++; 517+ } 518+ DumpInterfaceDescriptor(ifaceDesc); 519+ fprintf(stderr, "DEBUG: ParseInterfaceDescriptor out\n"); 520+ return OHUSB_SUCCESS; 521+} 522+ 523+int32_t ParseEndpointDescriptor(USBEndpoint &usbEndpoint, ohusb_endpoint_descriptor *epDesc) 524+{ 525+ fprintf(stderr, "DEBUG: ParseEndpointDescriptor enter\n"); 526+ if (epDesc == nullptr) { 527+ fprintf(stderr, "DEBUG: ParseEndpointDescriptor epDesc is nullptr\n"); 528+ return OHUSB_ERROR_NO_MEM; 529+ } 530+ epDesc->bDescriptorType = usbEndpoint.GetType(); 531+ epDesc->bEndpointAddress = usbEndpoint.GetAddress(); 532+ epDesc->bmAttributes = usbEndpoint.GetAttributes(); 533+ epDesc->wMaxPacketSize = usbEndpoint.GetMaxPacketSize(); 534+ epDesc->bInterval = usbEndpoint.GetInterval(); 535+ epDesc->bInterfaceId = usbEndpoint.GetInterfaceId(); 536+ epDesc->direction = usbEndpoint.GetDirection(); 537+ DumpEndpointDescriptor(epDesc); 538+ fprintf(stderr, "DEBUG: ParseEndpointDescriptor out\n"); 539+ return OHUSB_SUCCESS; 540+} 541+ 542+int32_t OH_SetConfiguration(ohusb_pipe *pipe, int configIndex) 543+{ 544+ fprintf(stderr, "DEBUG: OH_SetConfiguration enter\n"); 545+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance(); 546+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr}; 547+ USBConfig usbConfig; 548+ usbConfig.SetId(configIndex); 549+ int32_t ret = usbSrvClient.SetConfiguration(usbDevicePipe, usbConfig); 550+ if (ret != ERR_OK) { 551+ fprintf(stderr, "DEBUG: OH_SetConfiguration fail with ret = %d\n", ret); 552+ return OHUSB_ERROR_BUSY; 553+ } 554+ fprintf(stderr, "DEBUG: OH_SetConfiguration out\n"); 555+ return OHUSB_SUCCESS; 556+} 557+ 558+int32_t OH_SetInterface(ohusb_pipe *pipe, int interfaceId, int altIndex) 559+{ 560+ fprintf(stderr, "DEBUG: OH_SetInterface enter\n"); 561+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance(); 562+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr}; 563+ UsbInterface usbInterface; 564+ usbInterface.SetId(interfaceId); 565+ usbInterface.SetAlternateSetting(altIndex); 566+ int32_t ret = usbSrvClient.SetInterface(usbDevicePipe, usbInterface); 567+ if (ret != ERR_OK) { 568+ fprintf(stderr, "DEBUG: OH_SetInterface fail with ret = %d\n", ret); 569+ return OHUSB_ERROR_BUSY; 570+ } 571+ fprintf(stderr, "DEBUG: OH_SetInterface out\n"); 572+ return OHUSB_SUCCESS; 573+} 574+ 575+void ReleaseInterfaceDescriptor(ohusb_interface_descriptor *ifaceDesc) 576+{ 577+ if (ifaceDesc != nullptr) { 578+ SAFE_DELETE_ARRAY(ifaceDesc->endpoint); 579+ ifaceDesc->bNumEndpoints = 0; 580+ SAFE_DELETE_ARRAY(ifaceDesc); 581+ } 582+} 583+ 584+void ReleaseInterface(ohusb_interface *iface) 585+{ 586+ if (iface != nullptr) { 587+ for (uint8_t i = 0; i < iface->num_altsetting; i++) { 588+ ReleaseInterfaceDescriptor((iface->altsetting) + i); 589+ } 590+ iface->num_altsetting = 0; 591+ SAFE_DELETE_ARRAY(iface); 592+ } 593+} 594+ 595+void ReleaseConfigDescriptor(ohusb_config_descriptor *confDesc) 596+{ 597+ if (confDesc != nullptr) { 598+ for (uint8_t i = 0; i < confDesc->bNumInterfaces; i++) { 599+ ReleaseInterface((confDesc->interface) + i); 600+ } 601+ confDesc->bNumInterfaces = 0; 602+ SAFE_DELETE_ARRAY(confDesc); 603+ } 604+} 605+ 606+void ReleaseDeviceDescriptor(ohusb_device_descriptor *devDesc) 607+{ 608+ if (devDesc != nullptr) { 609+ for (uint8_t i = 0; i < devDesc->bNumConfigurations; i++) { 610+ ReleaseConfigDescriptor((devDesc->config) + i); 611+ } 612+ devDesc->bNumConfigurations = 0; 613+ SAFE_DELETE_ARRAY(devDesc); 614+ } 615+} 616+ 617+void DumpDeviceDescriptor(ohusb_device_descriptor *devDesc) 618+{ 619+ fprintf(stderr, "DEBUG: ------------------begin DeviceDescriptor------------------\n"); 620+ fprintf(stderr, "DEBUG: busNum = %x\n", devDesc->busNum); 621+ fprintf(stderr, "DEBUG: devAddr = %x\n", devDesc->devAddr); 622+ fprintf(stderr, "DEBUG: bcdUSB = %d\n", devDesc->bcdUSB); 623+ fprintf(stderr, "DEBUG: bDeviceClass = %x\n", devDesc->bDeviceClass); 624+ fprintf(stderr, "DEBUG: bDeviceSubClass = %x\n", devDesc->bDeviceSubClass); 625+ fprintf(stderr, "DEBUG: bDeviceProtocol = %x\n", devDesc->bDeviceProtocol); 626+ fprintf(stderr, "DEBUG: bMaxPacketSize0 = %x\n", devDesc->bMaxPacketSize0); 627+ fprintf(stderr, "DEBUG: idVendor = %d\n", devDesc->idVendor); 628+ fprintf(stderr, "DEBUG: idProduct = %d\n", devDesc->idProduct); 629+ fprintf(stderr, "DEBUG: bcdDevice = %d\n", devDesc->bcdDevice); 630+ fprintf(stderr, "DEBUG: iManufacturer = %x\n", devDesc->iManufacturer); 631+ fprintf(stderr, "DEBUG: iProduct = %x\n", devDesc->iProduct); 632+ fprintf(stderr, "DEBUG: iSerialNumber = %x\n", devDesc->iSerialNumber); 633+ fprintf(stderr, "DEBUG: bNumConfigurations = %x\n", devDesc->bNumConfigurations); 634+ fprintf(stderr, "DEBUG: ------------------end DeviceDescriptor------------------\n"); 635+ return; 636+} 637+ 638+void DumpConfigDescriptor(ohusb_config_descriptor *confDesc) 639+{ 640+ fprintf(stderr, "DEBUG: ------------------begin ConfigDescriptor------------------\n"); 641+ fprintf(stderr, "DEBUG: iConfiguration = %x\n", confDesc->iConfiguration); 642+ fprintf(stderr, "DEBUG: bmAttributes = %x\n", confDesc->bmAttributes); 643+ fprintf(stderr, "DEBUG: MaxPower = %x\n", confDesc->MaxPower); 644+ fprintf(stderr, "DEBUG: bNumInterfaces = %x\n", confDesc->bNumInterfaces); 645+ fprintf(stderr, "DEBUG: ------------------end ConfigDescriptor------------------\n"); 646+ return; 647+} 648+ 649+void DumpInterfaceDescriptor(ohusb_interface_descriptor *ifaceDesc) 650+{ 651+ fprintf(stderr, "DEBUG: ------------------begin InterfaceDescriptor------------------\n"); 652+ fprintf(stderr, "DEBUG: bInterfaceNumber = %x\n", ifaceDesc->bInterfaceNumber); 653+ fprintf(stderr, "DEBUG: bAlternateSetting = %x\n", ifaceDesc->bAlternateSetting); 654+ fprintf(stderr, "DEBUG: bInterfaceClass = %x\n", ifaceDesc->bInterfaceClass); 655+ fprintf(stderr, "DEBUG: bInterfaceSubClass = %x\n", ifaceDesc->bInterfaceSubClass); 656+ fprintf(stderr, "DEBUG: bInterfaceProtocol = %x\n", ifaceDesc->bInterfaceProtocol); 657+ fprintf(stderr, "DEBUG: bNumEndpoints = %x\n", ifaceDesc->bNumEndpoints); 658+ fprintf(stderr, "DEBUG: ------------------end InterfaceDescriptor------------------\n"); 659+ return; 660+} 661+ 662+void DumpEndpointDescriptor(ohusb_endpoint_descriptor *eptDesc) 663+{ 664+ fprintf(stderr, "DEBUG: ------------------begin EndpointDescriptor------------------\n"); 665+ fprintf(stderr, "DEBUG: bDescriptorType = %x\n", eptDesc->bDescriptorType); 666+ fprintf(stderr, "DEBUG: bEndpointAddress = %x\n", eptDesc->bEndpointAddress); 667+ fprintf(stderr, "DEBUG: bmAttributes = %x\n", eptDesc->bmAttributes); 668+ fprintf(stderr, "DEBUG: wMaxPacketSize = %d\n", eptDesc->wMaxPacketSize); 669+ fprintf(stderr, "DEBUG: bInterval = %x\n", eptDesc->bInterval); 670+ fprintf(stderr, "DEBUG: bInterfaceId = %x\n", eptDesc->bInterfaceId); 671+ fprintf(stderr, "DEBUG: direction = %d\n", eptDesc->direction); 672+ fprintf(stderr, "DEBUG: ------------------end EndpointDescriptor------------------\n"); 673+ return; 674+} 675+ 676+char *CopyString(const std::string &source) 677+{ 678+ auto len = source.length(); 679+ char *dest = new (std::nothrow) char[len + 1]; 680+ if (dest == nullptr) { 681+ fprintf(stderr, "DEBUG: CopyString allocate failed\n"); 682+ return nullptr; 683+ } 684+ if (strcpy_s(dest, len + 1, source.c_str()) != 0) { 685+ fprintf(stderr, "DEBUG: CopyString strcpy_s failed\n"); 686+ } 687+ dest[len] = '\0'; 688+ return dest; 689+} 690diff --git a/backend/usb_manager.h b/backend/usb_manager.h 691new file mode 100644 692index 0000000..e5e39fc 693--- /dev/null 694+++ b/backend/usb_manager.h 695@@ -0,0 +1,468 @@ 696+/* 697+ * Copyright (c) 2024 Huawei Device Co., Ltd. 698+ * Licensed under the Apache License, Version 2.0 (the "License"); 699+ * you may not use this file except in compliance with the License. 700+ * You may obtain a copy of the License at 701+ * 702+ * http://www.apache.org/licenses/LICENSE-2.0 703+ * 704+ * Unless required by applicable law or agreed to in writing, software 705+ * distributed under the License is distributed on an "AS IS" BASIS, 706+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 707+ * See the License for the specific language governing permissions and 708+ * limitations under the License. 709+ */ 710+ 711+#ifndef USB_MANAGER_H 712+#define USB_MANAGER_H 713+ 714+#include <cups/string-private.h> 715+ 716+#ifdef __cplusplus 717+extern "C" { 718+#endif 719+ 720+#include <stdbool.h> 721+ 722+#define OHUSB_TRANSFER_TYPE_MASK 0x03 /* in bmAttributes */ 723+#define OHUSB_ENDPOINT_DIR_MASK 0x80 724+ 725+const int OHUSB_CLASS_PRINTER = 7; 726+const uint16_t OHUSB_LANGUAGE_ID_ENGLISH = 0x409; 727+const int32_t OHUSB_GET_STRING_DESCRIPTOR_TIMEOUT = 1000; 728+const int32_t OHUSB_STRING_DESCRIPTOR_LENGTH_INDEX = 0; 729+ 730+const int32_t OHUSB_ENDPOINT_MAX_LENGTH = 512; 731+const int32_t OHUSB_CONTROLTRANSFER_READ_SLEEP = 100; 732+const int32_t OHUSB_CONTROLTRANSFER_READ_RETRY_MAX_TIMES = 20; 733+const int32_t OHUSB_BULKTRANSFER_WRITE_SLEEP = 1000; 734+const int32_t OHUSB_WRITE_RETRY_MAX_TIMES = 60; 735+const int32_t OHUSB_BULKTRANSFER_READ_TIMEOUT = 5000; 736+ 737+/* 738+ * Transfer type 739+ */ 740+typedef enum { 741+ /** Control transfer */ 742+ OHUSB_TRANSFER_TYPE_CONTROL = 0U, 743+ 744+ /** Isochronous transfer */ 745+ OHUSB_TRANSFER_TYPE_ISOCHRONOUS = 1U, 746+ 747+ /** Bulk transfer */ 748+ OHUSB_TRANSFER_TYPE_BULK = 2U, 749+ 750+ /** Interrupt transfer */ 751+ OHUSB_TRANSFER_TYPE_INTERRUPT = 3U, 752+ 753+ /** Bulk stream transfer */ 754+ OHUSB_TRANSFER_TYPE_BULK_STREAM = 4U 755+} ohusb_transfer_type; 756+ 757+/* 758+ * Request type bits. 759+ */ 760+typedef enum { 761+ /** Standard */ 762+ OHUSB_REQUEST_TYPE_STANDARD = (0x00 << 5), 763+ 764+ /** Class */ 765+ OHUSB_REQUEST_TYPE_CLASS = (0x01 << 5), 766+ 767+ /** Vendor */ 768+ OHUSB_REQUEST_TYPE_VENDOR = (0x02 << 5), 769+ 770+ /** Reserved */ 771+ OHUSB_REQUEST_TYPE_RESERVED = (0x03 << 5) 772+} ohusb_request_type; 773+ 774+/* 775+ * Endpoint direction. 776+ */ 777+typedef enum { 778+ /** Out: host-to-device */ 779+ OHUSB_ENDPOINT_OUT = 0x00, 780+ 781+ /** In: device-to-host */ 782+ OHUSB_ENDPOINT_IN = 0x80 783+} ohusb_endpoint_direction; 784+ 785+/* 786+ * Recipient bits of the requestType. 787+ */ 788+typedef enum { 789+ /** Device */ 790+ OHUSB_RECIPIENT_DEVICE = 0x00, 791+ 792+ /** Interface */ 793+ OHUSB_RECIPIENT_INTERFACE = 0x01, 794+ 795+ /** Endpoint */ 796+ OHUSB_RECIPIENT_ENDPOINT = 0x02, 797+ 798+ /** Other */ 799+ OHUSB_RECIPIENT_OTHER = 0x03 800+} ohusb_request_recipient; 801+ 802+/* 803+ * Standard requests 804+ */ 805+typedef enum { 806+ /** Request status of the specific recipient */ 807+ OHUSB_REQUEST_GET_STATUS = 0x00, 808+ 809+ /** Clear or disable a specific feature */ 810+ OHUSB_REQUEST_CLEAR_FEATURE = 0x01, 811+ 812+ /* 0x02 is reserved */ 813+ 814+ /** Set or enable a specific feature */ 815+ OHUSB_REQUEST_SET_FEATURE = 0x03, 816+ 817+ /* 0x04 is reserved */ 818+ 819+ /** Set device address for all future accesses */ 820+ OHUSB_REQUEST_SET_ADDRESS = 0x05, 821+ 822+ /** Get the specified descriptor */ 823+ OHUSB_REQUEST_GET_DESCRIPTOR = 0x06, 824+ 825+ /** Used to update existing descriptors or add new descriptors */ 826+ OHUSB_REQUEST_SET_DESCRIPTOR = 0x07, 827+ 828+ /** Get the current device configuration value */ 829+ OHUSB_REQUEST_GET_CONFIGURATION = 0x08, 830+ 831+ /** Set device configuration */ 832+ OHUSB_REQUEST_SET_CONFIGURATION = 0x09, 833+ 834+ /** Return the selected alternate setting for the specified interface */ 835+ OHUSB_REQUEST_GET_INTERFACE = 0x0a, 836+ 837+ /** Select an alternate interface for the specified interface */ 838+ OHUSB_REQUEST_SET_INTERFACE = 0x0b, 839+ 840+ /** Set then report an endpoint's synchronization frame */ 841+ OHUSB_REQUEST_SYNCH_FRAME = 0x0c, 842+ 843+ /** Sets both the U1 and U2 Exit Latency */ 844+ OHUSB_REQUEST_SET_SEL = 0x30, 845+ 846+ /** Delay from the time a host transmits a packet to the time it is 847+ * received by the device. */ 848+ OHUSB_SET_ISOCH_DELAY = 0x31 849+} ohusb_standard_request; 850+ 851+/* 852+ * Descriptor types as defined by the USB specification. 853+ */ 854+typedef enum { 855+ /** Device descriptor */ 856+ OHUSB_DT_DEVICE = 0x01, 857+ 858+ /** Configuration descriptor */ 859+ OHUSB_DT_CONFIG = 0x02, 860+ 861+ /** String descriptor */ 862+ OHUSB_DT_STRING = 0x03, 863+ 864+ /** Interface descriptor */ 865+ OHUSB_DT_INTERFACE = 0x04, 866+ 867+ /** Endpoint descriptor */ 868+ OHUSB_DT_ENDPOINT = 0x05, 869+ 870+ /** Interface Association Descriptor */ 871+ OHUSB_DT_INTERFACE_ASSOCIATION = 0x0b, 872+ 873+ /** BOS descriptor */ 874+ OHUSB_DT_BOS = 0x0f, 875+ 876+ /** Device Capability descriptor */ 877+ OHUSB_DT_DEVICE_CAPABILITY = 0x10, 878+ 879+ /** HID descriptor */ 880+ OHUSB_DT_HID = 0x21, 881+ 882+ /** HID report descriptor */ 883+ OHUSB_DT_REPORT = 0x22, 884+ 885+ /** Physical descriptor */ 886+ OHUSB_DT_PHYSICAL = 0x23, 887+ 888+ /** Hub descriptor */ 889+ OHUSB_DT_HUB = 0x29, 890+ 891+ /** SuperSpeed Hub descriptor */ 892+ OHUSB_DT_SUPERSPEED_HUB = 0x2a, 893+ 894+ /** SuperSpeed Endpoint Companion descriptor */ 895+ OHUSB_DT_SS_ENDPOINT_COMPANION = 0x30 896+} ohusb_descriptor_type; 897+ 898+/** 899+ * Error codes. 900+ */ 901+typedef enum { 902+ /** Success (no error) */ 903+ OHUSB_SUCCESS = 0, 904+ 905+ /** Input/output error */ 906+ OHUSB_ERROR_IO = -1, 907+ 908+ /** Invalid parameter */ 909+ OHUSB_ERROR_INVALID_PARAM = -2, 910+ 911+ /** Access denied (insufficient permissions) */ 912+ OHUSB_ERROR_ACCESS = -3, 913+ 914+ /** No such device (it may have been disconnected) */ 915+ OHUSB_ERROR_NO_DEVICE = -4, 916+ 917+ /** Entity not found */ 918+ OHUSB_ERROR_NOT_FOUND = -5, 919+ 920+ /** Resource busy */ 921+ OHUSB_ERROR_BUSY = -6, 922+ 923+ /** Operation timed out */ 924+ OHUSB_ERROR_TIMEOUT = -7, 925+ 926+ /** Overflow */ 927+ OHUSB_ERROR_OVERFLOW = -8, 928+ 929+ /** Pipe error */ 930+ OHUSB_ERROR_PIPE = -9, 931+ 932+ /** System call interrupted (perhaps due to signal) */ 933+ OHUSB_ERROR_INTERRUPTED = -10, 934+ 935+ /** Insufficient memory */ 936+ OHUSB_ERROR_NO_MEM = -11, 937+ 938+ /** Operation not supported or unimplemented on this platform */ 939+ OHUSB_ERROR_NOT_SUPPORTED = -12, 940+ 941+ /** Other error */ 942+ OHUSB_ERROR_OTHER = -99 943+} ohusb_error; 944+ 945+/** 946+ * A structure representing the parameter for usb control transfer. 947+ */ 948+typedef struct { 949+ /** Request type */ 950+ int32_t requestType; 951+ 952+ /** Request */ 953+ int32_t request; 954+ 955+ /** Value. Varies according to request */ 956+ int32_t value; 957+ 958+ /** Index. Varies according to request, typically used to pass an index 959+ * or offset */ 960+ int32_t index; 961+ 962+ /** timeout */ 963+ int32_t timeout; 964+} ohusb_control_transfer_parameter; 965+ 966+/** 967+ * A structure representing the standard USB endpoint descriptor. 968+ */ 969+typedef struct { 970+ /** Descriptor type */ 971+ uint8_t bDescriptorType; 972+ 973+ /** The address of the endpoint described by this descriptor. Bits 0:3 are 974+ * the endpoint number. Bits 4:6 are reserved. Bit 7 indicates direction. */ 975+ uint8_t bEndpointAddress; 976+ 977+ /** Attributes which apply to the endpoint when it is configured using 978+ * the bConfigurationValue. Bits 0:1 determine the transfer type. Bits 2:3 are 979+ * only used for isochronous endpoints. Bits 4:5 are also only used for 980+ * isochronous endpoints . Bits 6:7 are reserved. */ 981+ uint8_t bmAttributes; 982+ 983+ /** Maximum packet size this endpoint is capable of sending/receiving. */ 984+ uint16_t wMaxPacketSize; 985+ 986+ /** Interval for polling endpoint for data transfers. */ 987+ uint8_t bInterval; 988+ 989+ /** The interface id the endpoint belongs to. */ 990+ uint8_t bInterfaceId; 991+ 992+ /** The direction of the endpoint. */ 993+ uint32_t direction; 994+} ohusb_endpoint_descriptor; 995+ 996+/** 997+ * A structure representing the standard USB interface descriptor. 998+ */ 999+typedef struct { 1000+ /** Number of this interface */ 1001+ uint8_t bInterfaceNumber; 1002+ 1003+ /** Value used to select this alternate setting for this interface */ 1004+ uint8_t bAlternateSetting; 1005+ 1006+ /** USB-IF class code for this interface. */ 1007+ uint8_t bInterfaceClass; 1008+ 1009+ /** USB-IF subclass code for this interface, qualified by the 1010+ * bInterfaceClass value */ 1011+ uint8_t bInterfaceSubClass; 1012+ 1013+ /** USB-IF protocol code for this interface, qualified by the 1014+ * bInterfaceClass and bInterfaceSubClass values */ 1015+ uint8_t bInterfaceProtocol; 1016+ 1017+ /** Array of endpoint descriptors. This length of this array is determined 1018+ * by the bNumEndpoints field. */ 1019+ ohusb_endpoint_descriptor *endpoint; 1020+ 1021+ /** Number of endpoints used by this interface (excluding the control 1022+ * endpoint). */ 1023+ uint8_t bNumEndpoints; 1024+} ohusb_interface_descriptor; 1025+ 1026+/** 1027+ * A collection of alternate settings for a particular USB interface. 1028+ */ 1029+typedef struct { 1030+ /** Array of interface descriptors. The length of this array is determined 1031+ * by the num_altsetting field. */ 1032+ ohusb_interface_descriptor *altsetting; 1033+ 1034+ /** The number of alternate settings that belong to this interface. 1035+ * Must be non-negative. */ 1036+ int num_altsetting; 1037+} ohusb_interface; 1038+ 1039+/** 1040+ * A structure representing the standard USB configuration descriptor. 1041+ */ 1042+typedef struct { 1043+ /** Identifier value for this configuration */ 1044+ uint8_t iConfiguration; 1045+ 1046+ /** Configuration characteristics */ 1047+ uint8_t bmAttributes; 1048+ 1049+ /** Maximum power consumption of the USB device from this bus in this 1050+ * configuration when the device is fully operation. Expressed in units 1051+ * of 2 mA when the device is operating in high-speed mode and in units 1052+ * of 8 mA when the device is operating in super-speed mode. */ 1053+ uint8_t MaxPower; 1054+ 1055+ /** Array of interfaces supported by this configuration. The length of 1056+ * this array is determined by the bNumInterfaces field. */ 1057+ ohusb_interface *interface; 1058+ 1059+ /** Number of interfaces supported by this configuration */ 1060+ uint8_t bNumInterfaces; 1061+} ohusb_config_descriptor; 1062+ 1063+/** 1064+ * A structure representing the standard USB device descriptor. 1065+ */ 1066+typedef struct { 1067+ /** The bus num of the usb device. */ 1068+ uint8_t busNum; 1069+ 1070+ /** The device address of the usb device. */ 1071+ uint8_t devAddr; 1072+ 1073+ /** USB specification release number in binary-coded decimal. A value of 1074+ * 0x0200 indicates USB 2.0, 0x0110 indicates USB 1.1, etc. */ 1075+ uint16_t bcdUSB; 1076+ 1077+ /** USB-IF class code for the device. */ 1078+ uint8_t bDeviceClass; 1079+ 1080+ /** USB-IF subclass code for the device, qualified by the bDeviceClass 1081+ * value */ 1082+ uint8_t bDeviceSubClass; 1083+ 1084+ /** USB-IF protocol code for the device, qualified by the bDeviceClass and 1085+ * bDeviceSubClass values */ 1086+ uint8_t bDeviceProtocol; 1087+ 1088+ /** Maximum packet size for endpoint 0 */ 1089+ uint8_t bMaxPacketSize0; 1090+ 1091+ /** USB-IF vendor ID */ 1092+ uint16_t idVendor; 1093+ 1094+ /** USB-IF product ID */ 1095+ uint16_t idProduct; 1096+ 1097+ /** Device release number in binary-coded decimal */ 1098+ uint16_t bcdDevice; 1099+ 1100+ /** Index of string descriptor describing manufacturer */ 1101+ uint8_t iManufacturer; 1102+ 1103+ /** Index of string descriptor describing product */ 1104+ uint8_t iProduct; 1105+ 1106+ /** Index of string descriptor containing device serial number */ 1107+ uint8_t iSerialNumber; 1108+ 1109+ /** Array of configs supported by this device. The length of 1110+ * this array is determined by the bNumConfigurations field. */ 1111+ ohusb_config_descriptor *config; 1112+ 1113+ /** Number of configs supported by this device */ 1114+ uint8_t bNumConfigurations; 1115+} ohusb_device_descriptor; 1116+ 1117+/** 1118+ * A structure representing the pipe information to transfer data. 1119+ */ 1120+typedef struct { 1121+ /** The bus num of the usb device. */ 1122+ uint8_t busNum; 1123+ 1124+ /** The device address of the usb device. */ 1125+ uint8_t devAddr; 1126+} ohusb_pipe; 1127+ 1128+/** 1129+ * A structure representing the endpoint information to transfer data. 1130+ */ 1131+typedef struct { 1132+ /** The interface id to which the endpoint to transmit data belongs. */ 1133+ uint8_t bInterfaceId; 1134+ 1135+ /** The endpoint address to transfer data. */ 1136+ uint8_t bEndpointAddress; 1137+ 1138+ /** The interface id to be claimed. */ 1139+ int32_t bClaimedInterfaceId; 1140+} ohusb_transfer_pipe; 1141+ 1142+extern int32_t OH_GetDevices(ohusb_device_descriptor** list, ssize_t *numdevs); 1143+extern int32_t OH_OpenDevice(ohusb_device_descriptor *devDesc, ohusb_pipe **pipe); 1144+extern int32_t OH_CloseDevice(ohusb_pipe *pipe); 1145+extern int32_t OH_ClaimInterface(ohusb_pipe *pipe, int interfaceId, bool force); 1146+extern int32_t OH_ReleaseInterface(ohusb_pipe *pipe, int interfaceId); 1147+extern int32_t OH_BulkTransferRead( 1148+ ohusb_pipe *pipe, ohusb_transfer_pipe *tpipe, unsigned char *data, int length, int *transferred); 1149+extern int32_t OH_BulkTransferWrite( 1150+ ohusb_pipe *pipe, ohusb_transfer_pipe *tpipe, unsigned char *data, int length, int *transferred, int32_t timeout); 1151+extern int32_t OH_ControlTransferRead( 1152+ ohusb_pipe *pipe, ohusb_control_transfer_parameter *ctrlParam, unsigned char *data, uint16_t length); 1153+extern int32_t OH_ControlTransferWrite( 1154+ ohusb_pipe *pipe, ohusb_control_transfer_parameter *ctrlParam, unsigned char *data, uint16_t length); 1155+extern int32_t OH_GetStringDescriptor(ohusb_pipe *pipe, int descId, unsigned char *descriptor, int length); 1156+extern int32_t OH_SetConfiguration(ohusb_pipe *pipe, int configIndex); 1157+extern int32_t OH_SetInterface(ohusb_pipe *pipe, int interfaceId, int altIndex); 1158+ 1159+#ifdef __cplusplus 1160+} // extern "C" 1161+#endif 1162+ 1163+#endif /* USB_MANAGER_H */ 1164