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