• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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