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