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