mirror of
https://gitee.com/openharmony/third_party_cups
synced 2024-11-23 01:49:57 +00:00
a63449e56a
Signed-off-by: b30052170 <baozewei@huawei.com>
1149 lines
42 KiB
Diff
1149 lines
42 KiB
Diff
diff --git a/backend/usb_manager.cxx b/backend/usb_manager.cxx
|
|
new file mode 100644
|
|
index 0000000..f903774
|
|
--- /dev/null
|
|
+++ b/backend/usb_manager.cxx
|
|
@@ -0,0 +1,669 @@
|
|
+/*
|
|
+ * Copyright (c) 2024 Huawei Device Co., Ltd.
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
+ * you may not use this file except in compliance with the License.
|
|
+ * You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
+ * See the License for the specific language governing permissions and
|
|
+ * limitations under the License.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * OH USB interface code for CUPS.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * Include necessary headers.
|
|
+ */
|
|
+
|
|
+#include "usb_manager.h"
|
|
+#include "usb_srv_client.h"
|
|
+#include "v1_0/iusb_interface.h"
|
|
+
|
|
+#include <map>
|
|
+#include <regex>
|
|
+#include <string>
|
|
+#include <thread>
|
|
+#include <securec.h>
|
|
+
|
|
+using namespace std;
|
|
+using namespace OHOS;
|
|
+using namespace OHOS::USB;
|
|
+
|
|
+#define SAFE_DELETE(ptr) \
|
|
+ if ((ptr) != nullptr) { \
|
|
+ delete (ptr); \
|
|
+ (ptr) = nullptr; \
|
|
+ }
|
|
+
|
|
+#define SAFE_DELETE_ARRAY(ptr) \
|
|
+ if ((ptr) != nullptr) { \
|
|
+ delete[] (ptr); \
|
|
+ (ptr) = nullptr; \
|
|
+ }
|
|
+
|
|
+int32_t BulkTransferWriteData(
|
|
+ USBDevicePipe &usbDevicePipe, USBEndpoint &endpoint, const std::string &sendDataStr, int32_t timeout);
|
|
+int32_t ParseDeviceDescriptor(UsbDevice &usbDevice, ohusb_device_descriptor *devDesc);
|
|
+int32_t ParseConfigDescriptor(USBConfig &usbConfig, ohusb_config_descriptor *confDesc);
|
|
+int32_t ParseInterface(std::vector<UsbInterface> &usbIfaces, ohusb_interface *usbInterface, int32_t ifaceIndex);
|
|
+int32_t ParseInterfaceDescriptor(UsbInterface &usbInterface, ohusb_interface_descriptor *ifaceDesc);
|
|
+int32_t ParseEndpointDescriptor(USBEndpoint &usbEndpoint, ohusb_endpoint_descriptor *epDesc);
|
|
+void ReleaseDeviceDescriptor(ohusb_device_descriptor *devDesc);
|
|
+void ReleaseConfigDescriptor(ohusb_config_descriptor *confDesc);
|
|
+void ReleaseInterface(ohusb_interface *iface);
|
|
+void ReleaseInterfaceDescriptor(ohusb_interface_descriptor *ifaceDesc);
|
|
+void DumpDeviceDescriptor(ohusb_device_descriptor *devdesc);
|
|
+void DumpConfigDescriptor(ohusb_config_descriptor *confDesc);
|
|
+void DumpInterfaceDescriptor(ohusb_interface_descriptor *ifaceDesc);
|
|
+void DumpEndpointDescriptor(ohusb_endpoint_descriptor *eptDesc);
|
|
+char *CopyString(const std::string &source);
|
|
+
|
|
+int32_t OH_GetDevices(ohusb_device_descriptor** list, ssize_t *numdevs)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: OH_GetDevices enter\n");
|
|
+ vector<UsbDevice> devlist;
|
|
+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance();
|
|
+ auto getDevRet = usbSrvClient.GetDevices(devlist);
|
|
+ fprintf(stderr, "DEBUG: OH_GetDevices getDevRet = %d\n", getDevRet);
|
|
+ if (getDevRet != OHOS::ERR_OK) {
|
|
+ return OHUSB_ERROR_IO;
|
|
+ }
|
|
+ if (devlist.empty()) {
|
|
+ return OHUSB_SUCCESS;
|
|
+ }
|
|
+ ssize_t devCount = devlist.size();
|
|
+ *numdevs = 0;
|
|
+ fprintf(stderr, "DEBUG: OH_GetDevices device nums = %zd\n", devCount);
|
|
+
|
|
+ *list = (ohusb_device_descriptor *)calloc((size_t)devCount, sizeof(ohusb_device_descriptor));
|
|
+ if (*list == nullptr) {
|
|
+ fprintf(stderr, "DEBUG: OH_GetDevices list is nullptr\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+ for (ssize_t i = 0; i < devCount; i++) {
|
|
+ fprintf(stderr, "DEBUG: OH_GetDevices devlist[%zd] devAddr = %d, busNum = %d\n",
|
|
+ i, devlist[i].GetDevAddr(), devlist[i].GetBusNum());
|
|
+ if (ParseDeviceDescriptor(devlist[i], *list + i) != OHUSB_SUCCESS) {
|
|
+ return OHUSB_ERROR_IO;
|
|
+ }
|
|
+ (*numdevs)++;
|
|
+ }
|
|
+ return OHUSB_SUCCESS;
|
|
+}
|
|
+
|
|
+int32_t OH_OpenDevice(ohusb_device_descriptor *devDesc, ohusb_pipe **pipe)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: OH_OpenDevice enter\n");
|
|
+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance();
|
|
+ UsbDevice usbDevice;
|
|
+ usbDevice.SetBusNum(devDesc->busNum);
|
|
+ usbDevice.SetDevAddr(devDesc->devAddr);
|
|
+ USBDevicePipe usbDevicePipe;
|
|
+ auto openDevRet = usbSrvClient.OpenDevice(usbDevice, usbDevicePipe);
|
|
+ fprintf(stderr, "DEBUG: OH_OpenDevice getDevRet = %d\n", openDevRet);
|
|
+ if (openDevRet != OHOS::ERR_OK) {
|
|
+ return OHUSB_ERROR_IO;
|
|
+ }
|
|
+ *pipe = (ohusb_pipe *)calloc(1, sizeof(ohusb_pipe));
|
|
+ if (*pipe == nullptr) {
|
|
+ fprintf(stderr, "DEBUG: OH_OpenDevice pipe is nullptr\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+ (*pipe)->busNum = usbDevicePipe.GetBusNum();
|
|
+ (*pipe)->devAddr = usbDevicePipe.GetDevAddr();
|
|
+ fprintf(stderr, "DEBUG: OH_OpenDevice busNum=%d, devAddr=%d\n", (*pipe)->busNum, (*pipe)->devAddr);
|
|
+ fprintf(stderr, "DEBUG: OH_OpenDevice out\n");
|
|
+ return OHUSB_SUCCESS;
|
|
+}
|
|
+
|
|
+int32_t OH_CloseDevice(ohusb_pipe *pipe)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: OH_CloseDevice enter\n");
|
|
+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance();
|
|
+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr};
|
|
+ int32_t ret = usbSrvClient.Close(usbDevicePipe);
|
|
+ if (ret != ERR_OK) {
|
|
+ fprintf(stderr, "DEBUG: OH_CloseDevice fail with ret = %d\n", ret);
|
|
+ return OHUSB_ERROR_BUSY;
|
|
+ }
|
|
+ fprintf(stderr, "DEBUG: OH_CloseDevice out\n");
|
|
+ return OHUSB_SUCCESS;
|
|
+}
|
|
+
|
|
+int32_t OH_ClaimInterface(ohusb_pipe *pipe, int interfaceId, bool force)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: OH_ClaimInterface enter\n");
|
|
+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance();
|
|
+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr};
|
|
+ UsbInterface usbInterface;
|
|
+ usbInterface.SetId(interfaceId);
|
|
+ int32_t ret = usbSrvClient.ClaimInterface(usbDevicePipe, usbInterface, force);
|
|
+ if (ret != ERR_OK) {
|
|
+ fprintf(stderr, "DEBUG: OH_ClaimInterface fail with ret = %d\n", ret);
|
|
+ return OHUSB_ERROR_BUSY;
|
|
+ }
|
|
+ fprintf(stderr, "DEBUG: OH_ClaimInterface out\n");
|
|
+ return OHUSB_SUCCESS;
|
|
+}
|
|
+
|
|
+int32_t OH_ReleaseInterface(ohusb_pipe *pipe, int interfaceId)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: OH_ReleaseInterface enter\n");
|
|
+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance();
|
|
+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr};
|
|
+ UsbInterface usbInterface;
|
|
+ usbInterface.SetId(interfaceId);
|
|
+ int32_t ret = usbSrvClient.ReleaseInterface(usbDevicePipe, usbInterface);
|
|
+ if (ret != ERR_OK) {
|
|
+ fprintf(stderr, "DEBUG: OH_ReleaseInterface fail with ret = %d\n", ret);
|
|
+ return OHUSB_ERROR_BUSY;
|
|
+ }
|
|
+ fprintf(stderr, "DEBUG: OH_ReleaseInterface out\n");
|
|
+ return OHUSB_SUCCESS;
|
|
+}
|
|
+
|
|
+int32_t OH_BulkTransferRead(
|
|
+ ohusb_pipe *pipe, ohusb_transfer_pipe *tpipe, unsigned char *data, int length, int *transferred)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: OH_BulkTransferRead enter\n");
|
|
+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance();
|
|
+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr};
|
|
+ USBEndpoint endpoint;
|
|
+ endpoint.SetInterfaceId(tpipe->bInterfaceId);
|
|
+ endpoint.SetAddr(tpipe->bEndpointAddress);
|
|
+ std::vector<uint8_t> readTempBuffer;
|
|
+ size_t readSize = 0;
|
|
+ int32_t ret = usbSrvClient.BulkTransfer(usbDevicePipe, endpoint, readTempBuffer, OHUSB_BULKTRANSFER_READ_TIMEOUT);
|
|
+ fprintf(stderr, "DEBUG: OH_BulkTransferRead ret = %d\n", ret);
|
|
+ if (ret == HDF_DEV_ERR_NO_DEVICE) {
|
|
+ fprintf(stderr, "DEBUG: OH_BulkTransferRead HDF_DEV_ERR_NO_DEVICE, The device module has no device\n");
|
|
+ return OHUSB_ERROR_NO_DEVICE;
|
|
+ }
|
|
+ readSize = readTempBuffer.size();
|
|
+ if (ret == OHUSB_SUCCESS) {
|
|
+ std::copy(readTempBuffer.begin(), readTempBuffer.begin() + readSize, data);
|
|
+ fprintf(stderr, "DEBUG: OH_BulkTransferRead readSize = %zu\n", readSize);
|
|
+ *transferred = readSize;
|
|
+ return OHUSB_SUCCESS;
|
|
+ }
|
|
+
|
|
+ fprintf(stderr, "DEBUG: OH_BulkTransferRead read data time out\n");
|
|
+ return OHUSB_ERROR_TIMEOUT;
|
|
+}
|
|
+
|
|
+int32_t OH_BulkTransferWrite(
|
|
+ ohusb_pipe *pipe, ohusb_transfer_pipe *tpipe, unsigned char *data, int length, int *transferred, int32_t timeout)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: OH_BulkTransferRead enter\n");
|
|
+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr};
|
|
+ USBEndpoint endpoint;
|
|
+ endpoint.SetInterfaceId(tpipe->bInterfaceId);
|
|
+ endpoint.SetAddr(tpipe->bEndpointAddress);
|
|
+ int32_t ret = 0;
|
|
+ int leftDataLen = length;
|
|
+ while (leftDataLen > 0) {
|
|
+ fprintf(stderr, "DEBUG: OH_BulkTransferWrite leftDataLen waiting for transfer = %d\n", leftDataLen);
|
|
+ size_t len = leftDataLen > OHUSB_ENDPOINT_MAX_LENGTH ? OHUSB_ENDPOINT_MAX_LENGTH : leftDataLen;
|
|
+ std::string sendDataStr(reinterpret_cast<char *>(data), len);
|
|
+ ret = BulkTransferWriteData(usbDevicePipe, endpoint, sendDataStr, timeout);
|
|
+ if (ret != 0) {
|
|
+ return ret;
|
|
+ }
|
|
+ fprintf(stderr, "DEBUG: OH_BulkTransferWrite transferred data len = %zu\n", len);
|
|
+ leftDataLen -= len;
|
|
+ data += len;
|
|
+ }
|
|
+ *transferred = length - leftDataLen;
|
|
+ fprintf(stderr, "DEBUG: transferred data len = %d\n", *transferred);
|
|
+ fprintf(stderr, "DEBUG: OH_BulkTransferWrite out\n");
|
|
+ return OHUSB_SUCCESS;
|
|
+}
|
|
+
|
|
+int32_t BulkTransferWriteData(
|
|
+ USBDevicePipe &usbDevicePipe, USBEndpoint &endpoint, const std::string &sendDataStr, int32_t timeout)
|
|
+{
|
|
+ std::vector<uint8_t> vectorRequestBuffer;
|
|
+ vectorRequestBuffer.assign(sendDataStr.begin(), sendDataStr.end());
|
|
+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance();
|
|
+ uint32_t retryNum = 0;
|
|
+ int32_t ret = 0;
|
|
+ do {
|
|
+ fprintf(stderr, "DEBUG: BulkTransferWriteData write data retryCout: %d\n", retryNum);
|
|
+ ret = usbSrvClient.BulkTransfer(usbDevicePipe, endpoint, vectorRequestBuffer, timeout);
|
|
+ fprintf(stderr, "DEBUG: BulkTransferWrite ret: %d\n", ret);
|
|
+ if (ret == HDF_DEV_ERR_NO_DEVICE) {
|
|
+ fprintf(stderr, "DEBUG: BulkTransferWriteData no device\n");
|
|
+ return OHUSB_ERROR_NO_DEVICE;
|
|
+ }
|
|
+ if (ret == OHUSB_ERROR_TIMEOUT) {
|
|
+ std::this_thread::sleep_for(std::chrono::milliseconds(OHUSB_BULKTRANSFER_WRITE_SLEEP));
|
|
+ retryNum++;
|
|
+ }
|
|
+ } while (ret == OHUSB_ERROR_TIMEOUT && retryNum < OHUSB_WRITE_RETRY_MAX_TIMES);
|
|
+ if (ret != 0) {
|
|
+ fprintf(stderr, "DEBUG: Write data fail\n");
|
|
+ return ret;
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int32_t OH_ControlTransferRead(
|
|
+ ohusb_pipe *pipe, ohusb_control_transfer_parameter *ctrlParam, unsigned char *data, uint16_t length)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferRead enter\n");
|
|
+ if (pipe == nullptr || ctrlParam == nullptr) {
|
|
+ fprintf(stderr, "DEBUG: pipe or ctrlParam is nullptr\n");
|
|
+ return OHUSB_ERROR_IO;
|
|
+ }
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferRead busNum=%d, devAddr=%d\n", pipe->busNum, pipe->devAddr);
|
|
+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr};
|
|
+ int32_t requestType = ctrlParam->requestType;
|
|
+ int32_t request = ctrlParam->request;
|
|
+ int32_t value = ctrlParam->value;
|
|
+ int32_t index = ctrlParam->index;
|
|
+ int32_t timeOut = ctrlParam->timeout;
|
|
+ const HDI::Usb::V1_0::UsbCtrlTransfer tctrl = {requestType, request, value, index, timeOut};
|
|
+ std::vector<uint8_t> bufferData(length, 0);
|
|
+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance();
|
|
+ uint32_t retryNum = 0;
|
|
+ int32_t ret = OHUSB_SUCCESS;
|
|
+ do {
|
|
+ ret = usbSrvClient.ControlTransfer(usbDevicePipe, tctrl, bufferData);
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferRead ret = %d\n", ret);
|
|
+ if (ret == OHUSB_ERROR_TIMEOUT) {
|
|
+ std::this_thread::sleep_for(std::chrono::milliseconds(OHUSB_CONTROLTRANSFER_READ_SLEEP));
|
|
+ retryNum++;
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferRead retryCount: %d\n", retryNum);
|
|
+ }
|
|
+ } while (ret == OHUSB_ERROR_TIMEOUT && retryNum < OHUSB_CONTROLTRANSFER_READ_RETRY_MAX_TIMES);
|
|
+ if (ret != 0) {
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferRead fail\n");
|
|
+ return OHUSB_ERROR_IO;
|
|
+ }
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferRead bufferData size = %zu\n", bufferData.size());
|
|
+
|
|
+ if ((value >> 8) == OHUSB_DT_STRING) {
|
|
+ int bufferLen = bufferData.size();
|
|
+ uint16_t *wbuf = new (std::nothrow) uint16_t[bufferLen + 1]();
|
|
+ if (wbuf == nullptr) {
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferRead wbuf is nullptr.\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+ for (uint32_t i = 0; i < bufferLen - 2; ++i) {
|
|
+ wbuf[i] = bufferData[i + 2];
|
|
+ }
|
|
+ std::wstring wstr(reinterpret_cast<wchar_t *>(wbuf), (bufferLen - 2) / 2);
|
|
+ std::string buffer(wstr.begin(), wstr.end());
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferRead buffer = %s\n", buffer.c_str());
|
|
+ if (memcpy_s(data, length, buffer.c_str(), buffer.length()) != 0) {
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferRead memcpy_s fail.\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+ } else if (memcpy_s(data, length, bufferData.data(), bufferData.size()) != 0) {
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferRead memcpy_s fail.\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferRead out\n");
|
|
+ return bufferData.size();
|
|
+}
|
|
+
|
|
+int32_t OH_ControlTransferWrite(
|
|
+ ohusb_pipe *pipe, ohusb_control_transfer_parameter *ctrlParam, unsigned char *data, uint16_t length)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferWrite enter\n");
|
|
+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr};
|
|
+ int32_t requestType = ctrlParam->requestType;
|
|
+ int32_t request = ctrlParam->request;
|
|
+ int32_t value = ctrlParam->value;
|
|
+ int32_t index = ctrlParam->index;
|
|
+ int32_t timeOut = ctrlParam->timeout;
|
|
+ const HDI::Usb::V1_0::UsbCtrlTransfer tctrl = {requestType, request, value, index, timeOut};
|
|
+ std::vector<uint8_t> bufferData(length, 0);
|
|
+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance();
|
|
+ int32_t ret = usbSrvClient.ControlTransfer(usbDevicePipe, tctrl, bufferData);
|
|
+ if (ret != 0) {
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferWrite fail with ret = %d\n", ret);
|
|
+ return OHUSB_ERROR_IO;
|
|
+ }
|
|
+
|
|
+ fprintf(stderr, "DEBUG: OH_ControlTransferRead out\n");
|
|
+ return length;
|
|
+}
|
|
+
|
|
+int32_t OH_GetStringDescriptor(ohusb_pipe *pipe, int descId, unsigned char *descriptor, int length)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: OH_GetStringDescriptor enter\n");
|
|
+ if (descId == 0) {
|
|
+ return OHUSB_ERROR_INVALID_PARAM;
|
|
+ }
|
|
+ ohusb_control_transfer_parameter ctrlParam = {
|
|
+ OHUSB_ENDPOINT_IN,
|
|
+ OHUSB_REQUEST_GET_DESCRIPTOR,
|
|
+ (uint16_t)((OHUSB_DT_STRING << 8) | descId),
|
|
+ OHUSB_LANGUAGE_ID_ENGLISH,
|
|
+ OHUSB_GET_STRING_DESCRIPTOR_TIMEOUT
|
|
+ };
|
|
+ auto ret = OH_ControlTransferRead(pipe, &ctrlParam, descriptor, length);
|
|
+ if (ret < 0) {
|
|
+ fprintf(stderr, "DEBUG: OH_GetStringDescriptor OH_ControlTransferRead failed\n");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ fprintf(stderr, "DEBUG: OH_GetStringDescriptor out\n");
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int32_t ParseDeviceDescriptor(UsbDevice &usbDevice, ohusb_device_descriptor *devDesc)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: ParseDeviceDescriptor enter\n");
|
|
+ if (devDesc == nullptr) {
|
|
+ fprintf(stderr, "DEBUG: ParseDeviceDescriptor devDesc is nullptr\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+
|
|
+ devDesc->devAddr = usbDevice.GetDevAddr();
|
|
+ devDesc->busNum = usbDevice.GetBusNum();
|
|
+ devDesc->bcdUSB = usbDevice.GetbcdUSB();
|
|
+ devDesc->bDeviceClass = usbDevice.GetClass();
|
|
+ devDesc->bDeviceSubClass = usbDevice.GetSubclass();
|
|
+ devDesc->bDeviceProtocol = usbDevice.GetProtocol();
|
|
+ devDesc->bMaxPacketSize0 = usbDevice.GetbMaxPacketSize0();
|
|
+ devDesc->idVendor = usbDevice.GetVendorId();
|
|
+ devDesc->idProduct = usbDevice.GetProductId();
|
|
+ devDesc->iManufacturer = usbDevice.GetiManufacturer();
|
|
+ devDesc->iProduct = usbDevice.GetiProduct();
|
|
+ devDesc->iSerialNumber = usbDevice.GetiSerialNumber();
|
|
+ devDesc->bNumConfigurations = 0;
|
|
+ ohusb_config_descriptor *config =
|
|
+ (ohusb_config_descriptor *)calloc((size_t)usbDevice.GetConfigCount(), sizeof(ohusb_config_descriptor));
|
|
+ if (config == nullptr) {
|
|
+ fprintf(stderr, "DEBUG: ParseDeviceDescriptor config is null.\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+ devDesc->config = config;
|
|
+
|
|
+ for (int i = 0; i < usbDevice.GetConfigCount(); i++) {
|
|
+ USBConfig usbConfig;
|
|
+ usbDevice.GetConfig(i, usbConfig);
|
|
+ if (ParseConfigDescriptor(usbConfig, config + i) != OHUSB_SUCCESS) {
|
|
+ return OHUSB_ERROR_IO;
|
|
+ }
|
|
+ (devDesc->bNumConfigurations)++;
|
|
+ }
|
|
+ DumpDeviceDescriptor(devDesc);
|
|
+ fprintf(stderr, "DEBUG: ParseDeviceDescriptor out\n");
|
|
+ return OHUSB_SUCCESS;
|
|
+}
|
|
+
|
|
+int32_t ParseConfigDescriptor(USBConfig &usbConfig, ohusb_config_descriptor *confDesc)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: ParseConfigDescriptor enter\n");
|
|
+ if (confDesc == nullptr) {
|
|
+ fprintf(stderr, "DEBUG: ParseConfigDescriptor confDesc is nullptr\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+ confDesc->iConfiguration = usbConfig.GetId();
|
|
+ confDesc->bmAttributes = usbConfig.GetAttributes();
|
|
+ confDesc->MaxPower = usbConfig.GetMaxPower();
|
|
+
|
|
+ std::vector<UsbInterface> usbIfaces = usbConfig.GetInterfaces();
|
|
+ int32_t ifaceCount = usbIfaces.size() > 0 ? usbIfaces[usbIfaces.size() - 1].GetId() + 1 : 0;
|
|
+
|
|
+ confDesc->bNumInterfaces = 0;
|
|
+ ohusb_interface *usbInterface =
|
|
+ (ohusb_interface *)calloc((size_t)ifaceCount, sizeof(ohusb_interface));
|
|
+ if (usbInterface == nullptr) {
|
|
+ fprintf(stderr, "DEBUG: ParseConfigDescriptor usbInterface is nullptr\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+ confDesc->interface = usbInterface;
|
|
+ for (int32_t ifaceIndex = 0; ifaceIndex < ifaceCount; ifaceIndex++) {
|
|
+ if (ParseInterface(usbIfaces, usbInterface + ifaceIndex, ifaceIndex) != OHUSB_SUCCESS) {
|
|
+ return OHUSB_ERROR_IO;
|
|
+ }
|
|
+ (confDesc->bNumInterfaces)++;
|
|
+ }
|
|
+ DumpConfigDescriptor(confDesc);
|
|
+ fprintf(stderr, "DEBUG: ParseConfigDescriptor out\n");
|
|
+ return OHUSB_SUCCESS;
|
|
+}
|
|
+
|
|
+int32_t ParseInterface(std::vector<UsbInterface> &usbIfaces, ohusb_interface *usbInterface, int32_t ifaceIndex)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: ParseInterface ifaceIndex=%d\n", ifaceIndex);
|
|
+ for (int32_t usbIfacesIndex = 0; usbIfacesIndex < usbIfaces.size(); usbIfacesIndex++) {
|
|
+ if (usbIfaces[usbIfacesIndex].GetId() == ifaceIndex) {
|
|
+ ohusb_interface_descriptor *altsetting;
|
|
+ altsetting = (ohusb_interface_descriptor *)
|
|
+ calloc((size_t)(usbInterface->num_altsetting + 1), sizeof(*altsetting));
|
|
+ if (altsetting == nullptr) {
|
|
+ fprintf(stderr, "DEBUG: ParseInterface altsetting is nullptr\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+ if (usbInterface->num_altsetting != 0 &&
|
|
+ memcpy_s(altsetting, sizeof(*altsetting) * (size_t)(usbInterface->num_altsetting),
|
|
+ usbInterface->altsetting, sizeof(*altsetting) * (size_t)(usbInterface->num_altsetting)) != 0) {
|
|
+ fprintf(stderr, "DEBUG: ParseInterface memcpy_s fail.\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+ usbInterface->altsetting = altsetting;
|
|
+ if (ParseInterfaceDescriptor(usbIfaces[usbIfacesIndex], altsetting + (usbInterface->num_altsetting))
|
|
+ != OHUSB_SUCCESS) {
|
|
+ return OHUSB_ERROR_IO;
|
|
+ }
|
|
+ usbInterface->num_altsetting++;
|
|
+ }
|
|
+ }
|
|
+ fprintf(stderr, "DEBUG: ParseInterface num_altsetting=%d\n", usbInterface->num_altsetting);
|
|
+ return OHUSB_SUCCESS;
|
|
+}
|
|
+
|
|
+int32_t ParseInterfaceDescriptor(UsbInterface &usbInterface, ohusb_interface_descriptor *ifaceDesc)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: ParseInterfaceDescriptor enter\n");
|
|
+ if (ifaceDesc == nullptr) {
|
|
+ fprintf(stderr, "DEBUG: ParseInterfaceDescriptor ifaceDesc is nullptr\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+ ifaceDesc->bInterfaceNumber = usbInterface.GetId();
|
|
+ ifaceDesc->bAlternateSetting = usbInterface.GetAlternateSetting();
|
|
+ ifaceDesc->bInterfaceClass = usbInterface.GetClass();
|
|
+ ifaceDesc->bInterfaceSubClass = usbInterface.GetSubClass();
|
|
+ ifaceDesc->bInterfaceProtocol = usbInterface.GetProtocol();
|
|
+ ifaceDesc->bNumEndpoints = 0;
|
|
+ fprintf(stderr, "DEBUG: ParseInterfaceDescriptor class=%x, subclass=%x, protocol=%x.\n",
|
|
+ usbInterface.GetClass(), usbInterface.GetSubClass(), usbInterface.GetProtocol());
|
|
+ ohusb_endpoint_descriptor *endpoint;
|
|
+ endpoint = (ohusb_endpoint_descriptor *)
|
|
+ calloc((size_t)usbInterface.GetEndpointCount(), sizeof(ohusb_endpoint_descriptor));
|
|
+ if (endpoint == nullptr) {
|
|
+ fprintf(stderr, "DEBUG: endpoint is null.\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+ ifaceDesc->endpoint = endpoint;
|
|
+ std::vector<USBEndpoint> endpoints = usbInterface.GetEndpoints();
|
|
+ for (int i = 0; i < usbInterface.GetEndpointCount(); i++) {
|
|
+ if (ParseEndpointDescriptor(endpoints[i], endpoint + i) != OHUSB_SUCCESS) {
|
|
+ return OHUSB_ERROR_IO;
|
|
+ }
|
|
+ (ifaceDesc->bNumEndpoints)++;
|
|
+ }
|
|
+ DumpInterfaceDescriptor(ifaceDesc);
|
|
+ fprintf(stderr, "DEBUG: ParseInterfaceDescriptor out\n");
|
|
+ return OHUSB_SUCCESS;
|
|
+}
|
|
+
|
|
+int32_t ParseEndpointDescriptor(USBEndpoint &usbEndpoint, ohusb_endpoint_descriptor *epDesc)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: ParseEndpointDescriptor enter\n");
|
|
+ if (epDesc == nullptr) {
|
|
+ fprintf(stderr, "DEBUG: ParseEndpointDescriptor epDesc is nullptr\n");
|
|
+ return OHUSB_ERROR_NO_MEM;
|
|
+ }
|
|
+ epDesc->bDescriptorType = usbEndpoint.GetType();
|
|
+ epDesc->bEndpointAddress = usbEndpoint.GetAddress();
|
|
+ epDesc->bmAttributes = usbEndpoint.GetAttributes();
|
|
+ epDesc->wMaxPacketSize = usbEndpoint.GetMaxPacketSize();
|
|
+ epDesc->bInterval = usbEndpoint.GetInterval();
|
|
+ epDesc->bInterfaceId = usbEndpoint.GetInterfaceId();
|
|
+ epDesc->direction = usbEndpoint.GetDirection();
|
|
+ DumpEndpointDescriptor(epDesc);
|
|
+ fprintf(stderr, "DEBUG: ParseEndpointDescriptor out\n");
|
|
+ return OHUSB_SUCCESS;
|
|
+}
|
|
+
|
|
+int32_t OH_SetConfiguration(ohusb_pipe *pipe, int configIndex)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: OH_SetConfiguration enter\n");
|
|
+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance();
|
|
+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr};
|
|
+ USBConfig usbConfig;
|
|
+ usbConfig.SetId(configIndex);
|
|
+ int32_t ret = usbSrvClient.SetConfiguration(usbDevicePipe, usbConfig);
|
|
+ if (ret != ERR_OK) {
|
|
+ fprintf(stderr, "DEBUG: OH_SetConfiguration fail with ret = %d\n", ret);
|
|
+ return OHUSB_ERROR_BUSY;
|
|
+ }
|
|
+ fprintf(stderr, "DEBUG: OH_SetConfiguration out\n");
|
|
+ return OHUSB_SUCCESS;
|
|
+}
|
|
+
|
|
+int32_t OH_SetInterface(ohusb_pipe *pipe, int interfaceId, int altIndex)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: OH_SetInterface enter\n");
|
|
+ auto &usbSrvClient = OHOS::USB::UsbSrvClient::GetInstance();
|
|
+ USBDevicePipe usbDevicePipe = {pipe->busNum, pipe->devAddr};
|
|
+ UsbInterface usbInterface;
|
|
+ usbInterface.SetId(interfaceId);
|
|
+ usbInterface.SetAlternateSetting(altIndex);
|
|
+ int32_t ret = usbSrvClient.SetInterface(usbDevicePipe, usbInterface);
|
|
+ if (ret != ERR_OK) {
|
|
+ fprintf(stderr, "DEBUG: OH_SetInterface fail with ret = %d\n", ret);
|
|
+ return OHUSB_ERROR_BUSY;
|
|
+ }
|
|
+ fprintf(stderr, "DEBUG: OH_SetInterface out\n");
|
|
+ return OHUSB_SUCCESS;
|
|
+}
|
|
+
|
|
+void ReleaseInterfaceDescriptor(ohusb_interface_descriptor *ifaceDesc)
|
|
+{
|
|
+ if (ifaceDesc != nullptr) {
|
|
+ SAFE_DELETE_ARRAY(ifaceDesc->endpoint);
|
|
+ ifaceDesc->bNumEndpoints = 0;
|
|
+ SAFE_DELETE_ARRAY(ifaceDesc);
|
|
+ }
|
|
+}
|
|
+
|
|
+void ReleaseInterface(ohusb_interface *iface)
|
|
+{
|
|
+ if (iface != nullptr) {
|
|
+ for (uint8_t i = 0; i < iface->num_altsetting; i++) {
|
|
+ ReleaseInterfaceDescriptor((iface->altsetting) + i);
|
|
+ }
|
|
+ iface->num_altsetting = 0;
|
|
+ SAFE_DELETE_ARRAY(iface);
|
|
+ }
|
|
+}
|
|
+
|
|
+void ReleaseConfigDescriptor(ohusb_config_descriptor *confDesc)
|
|
+{
|
|
+ if (confDesc != nullptr) {
|
|
+ for (uint8_t i = 0; i < confDesc->bNumInterfaces; i++) {
|
|
+ ReleaseInterface((confDesc->interface) + i);
|
|
+ }
|
|
+ confDesc->bNumInterfaces = 0;
|
|
+ SAFE_DELETE_ARRAY(confDesc);
|
|
+ }
|
|
+}
|
|
+
|
|
+void ReleaseDeviceDescriptor(ohusb_device_descriptor *devDesc)
|
|
+{
|
|
+ if (devDesc != nullptr) {
|
|
+ for (uint8_t i = 0; i < devDesc->bNumConfigurations; i++) {
|
|
+ ReleaseConfigDescriptor((devDesc->config) + i);
|
|
+ }
|
|
+ devDesc->bNumConfigurations = 0;
|
|
+ SAFE_DELETE_ARRAY(devDesc);
|
|
+ }
|
|
+}
|
|
+
|
|
+void DumpDeviceDescriptor(ohusb_device_descriptor *devDesc)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: ------------------begin DeviceDescriptor------------------\n");
|
|
+ fprintf(stderr, "DEBUG: busNum = %x\n", devDesc->busNum);
|
|
+ fprintf(stderr, "DEBUG: devAddr = %x\n", devDesc->devAddr);
|
|
+ fprintf(stderr, "DEBUG: bcdUSB = %d\n", devDesc->bcdUSB);
|
|
+ fprintf(stderr, "DEBUG: bDeviceClass = %x\n", devDesc->bDeviceClass);
|
|
+ fprintf(stderr, "DEBUG: bDeviceSubClass = %x\n", devDesc->bDeviceSubClass);
|
|
+ fprintf(stderr, "DEBUG: bDeviceProtocol = %x\n", devDesc->bDeviceProtocol);
|
|
+ fprintf(stderr, "DEBUG: bMaxPacketSize0 = %x\n", devDesc->bMaxPacketSize0);
|
|
+ fprintf(stderr, "DEBUG: idVendor = %d\n", devDesc->idVendor);
|
|
+ fprintf(stderr, "DEBUG: idProduct = %d\n", devDesc->idProduct);
|
|
+ fprintf(stderr, "DEBUG: bcdDevice = %d\n", devDesc->bcdDevice);
|
|
+ fprintf(stderr, "DEBUG: iManufacturer = %x\n", devDesc->iManufacturer);
|
|
+ fprintf(stderr, "DEBUG: iProduct = %x\n", devDesc->iProduct);
|
|
+ fprintf(stderr, "DEBUG: iSerialNumber = %x\n", devDesc->iSerialNumber);
|
|
+ fprintf(stderr, "DEBUG: bNumConfigurations = %x\n", devDesc->bNumConfigurations);
|
|
+ fprintf(stderr, "DEBUG: ------------------end DeviceDescriptor------------------\n");
|
|
+ return;
|
|
+}
|
|
+
|
|
+void DumpConfigDescriptor(ohusb_config_descriptor *confDesc)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: ------------------begin ConfigDescriptor------------------\n");
|
|
+ fprintf(stderr, "DEBUG: iConfiguration = %x\n", confDesc->iConfiguration);
|
|
+ fprintf(stderr, "DEBUG: bmAttributes = %x\n", confDesc->bmAttributes);
|
|
+ fprintf(stderr, "DEBUG: MaxPower = %x\n", confDesc->MaxPower);
|
|
+ fprintf(stderr, "DEBUG: bNumInterfaces = %x\n", confDesc->bNumInterfaces);
|
|
+ fprintf(stderr, "DEBUG: ------------------end ConfigDescriptor------------------\n");
|
|
+ return;
|
|
+}
|
|
+
|
|
+void DumpInterfaceDescriptor(ohusb_interface_descriptor *ifaceDesc)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: ------------------begin InterfaceDescriptor------------------\n");
|
|
+ fprintf(stderr, "DEBUG: bInterfaceNumber = %x\n", ifaceDesc->bInterfaceNumber);
|
|
+ fprintf(stderr, "DEBUG: bAlternateSetting = %x\n", ifaceDesc->bAlternateSetting);
|
|
+ fprintf(stderr, "DEBUG: bInterfaceClass = %x\n", ifaceDesc->bInterfaceClass);
|
|
+ fprintf(stderr, "DEBUG: bInterfaceSubClass = %x\n", ifaceDesc->bInterfaceSubClass);
|
|
+ fprintf(stderr, "DEBUG: bInterfaceProtocol = %x\n", ifaceDesc->bInterfaceProtocol);
|
|
+ fprintf(stderr, "DEBUG: bNumEndpoints = %x\n", ifaceDesc->bNumEndpoints);
|
|
+ fprintf(stderr, "DEBUG: ------------------end InterfaceDescriptor------------------\n");
|
|
+ return;
|
|
+}
|
|
+
|
|
+void DumpEndpointDescriptor(ohusb_endpoint_descriptor *eptDesc)
|
|
+{
|
|
+ fprintf(stderr, "DEBUG: ------------------begin EndpointDescriptor------------------\n");
|
|
+ fprintf(stderr, "DEBUG: bDescriptorType = %x\n", eptDesc->bDescriptorType);
|
|
+ fprintf(stderr, "DEBUG: bEndpointAddress = %x\n", eptDesc->bEndpointAddress);
|
|
+ fprintf(stderr, "DEBUG: bmAttributes = %x\n", eptDesc->bmAttributes);
|
|
+ fprintf(stderr, "DEBUG: wMaxPacketSize = %d\n", eptDesc->wMaxPacketSize);
|
|
+ fprintf(stderr, "DEBUG: bInterval = %x\n", eptDesc->bInterval);
|
|
+ fprintf(stderr, "DEBUG: bInterfaceId = %x\n", eptDesc->bInterfaceId);
|
|
+ fprintf(stderr, "DEBUG: direction = %d\n", eptDesc->direction);
|
|
+ fprintf(stderr, "DEBUG: ------------------end EndpointDescriptor------------------\n");
|
|
+ return;
|
|
+}
|
|
+
|
|
+char *CopyString(const std::string &source)
|
|
+{
|
|
+ auto len = source.length();
|
|
+ char *dest = new (std::nothrow) char[len + 1];
|
|
+ if (dest == nullptr) {
|
|
+ fprintf(stderr, "DEBUG: CopyString allocate failed\n");
|
|
+ return nullptr;
|
|
+ }
|
|
+ if (strcpy_s(dest, len + 1, source.c_str()) != 0) {
|
|
+ fprintf(stderr, "DEBUG: CopyString strcpy_s failed\n");
|
|
+ }
|
|
+ dest[len] = '\0';
|
|
+ return dest;
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/backend/usb_manager.h b/backend/usb_manager.h
|
|
new file mode 100644
|
|
index 0000000..30ced79
|
|
--- /dev/null
|
|
+++ b/backend/usb_manager.h
|
|
@@ -0,0 +1,465 @@
|
|
+/*
|
|
+ * Copyright (c) 2024 Huawei Device Co., Ltd.
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
+ * you may not use this file except in compliance with the License.
|
|
+ * You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
|
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
+ * See the License for the specific language governing permissions and
|
|
+ * limitations under the License.
|
|
+ */
|
|
+
|
|
+#ifndef USB_MANAGER_H
|
|
+#define USB_MANAGER_H
|
|
+
|
|
+#include <cups/string-private.h>
|
|
+
|
|
+#ifdef __cplusplus
|
|
+extern "C" {
|
|
+#endif
|
|
+
|
|
+#include <stdbool.h>
|
|
+
|
|
+#define OHUSB_TRANSFER_TYPE_MASK 0x03 /* in bmAttributes */
|
|
+#define OHUSB_ENDPOINT_DIR_MASK 0x80
|
|
+
|
|
+const int OHUSB_CLASS_PRINTER = 7;
|
|
+const uint16_t OHUSB_LANGUAGE_ID_ENGLISH = 0x409;
|
|
+const int32_t OHUSB_GET_STRING_DESCRIPTOR_TIMEOUT = 1000;
|
|
+const int32_t OHUSB_STRING_DESCRIPTOR_LENGTH_INDEX = 0;
|
|
+
|
|
+const int32_t OHUSB_ENDPOINT_MAX_LENGTH = 512;
|
|
+const int32_t OHUSB_CONTROLTRANSFER_READ_SLEEP = 100;
|
|
+const int32_t OHUSB_CONTROLTRANSFER_READ_RETRY_MAX_TIMES = 20;
|
|
+const int32_t OHUSB_BULKTRANSFER_WRITE_SLEEP = 1000;
|
|
+const int32_t OHUSB_WRITE_RETRY_MAX_TIMES = 20;
|
|
+const int32_t OHUSB_BULKTRANSFER_READ_TIMEOUT = 5000;
|
|
+
|
|
+/*
|
|
+ * Transfer type
|
|
+ */
|
|
+typedef enum {
|
|
+ /** Control transfer */
|
|
+ OHUSB_TRANSFER_TYPE_CONTROL = 0U,
|
|
+
|
|
+ /** Isochronous transfer */
|
|
+ OHUSB_TRANSFER_TYPE_ISOCHRONOUS = 1U,
|
|
+
|
|
+ /** Bulk transfer */
|
|
+ OHUSB_TRANSFER_TYPE_BULK = 2U,
|
|
+
|
|
+ /** Interrupt transfer */
|
|
+ OHUSB_TRANSFER_TYPE_INTERRUPT = 3U,
|
|
+
|
|
+ /** Bulk stream transfer */
|
|
+ OHUSB_TRANSFER_TYPE_BULK_STREAM = 4U
|
|
+} ohusb_transfer_type;
|
|
+
|
|
+/*
|
|
+ * Request type bits.
|
|
+ */
|
|
+typedef enum {
|
|
+ /** Standard */
|
|
+ OHUSB_REQUEST_TYPE_STANDARD = (0x00 << 5),
|
|
+
|
|
+ /** Class */
|
|
+ OHUSB_REQUEST_TYPE_CLASS = (0x01 << 5),
|
|
+
|
|
+ /** Vendor */
|
|
+ OHUSB_REQUEST_TYPE_VENDOR = (0x02 << 5),
|
|
+
|
|
+ /** Reserved */
|
|
+ OHUSB_REQUEST_TYPE_RESERVED = (0x03 << 5)
|
|
+} ohusb_request_type;
|
|
+
|
|
+/*
|
|
+ * Endpoint direction.
|
|
+ */
|
|
+typedef enum {
|
|
+ /** Out: host-to-device */
|
|
+ OHUSB_ENDPOINT_OUT = 0x00,
|
|
+
|
|
+ /** In: device-to-host */
|
|
+ OHUSB_ENDPOINT_IN = 0x80
|
|
+} ohusb_endpoint_direction;
|
|
+
|
|
+/*
|
|
+ * Recipient bits of the requestType.
|
|
+ */
|
|
+typedef enum {
|
|
+ /** Device */
|
|
+ OHUSB_RECIPIENT_DEVICE = 0x00,
|
|
+
|
|
+ /** Interface */
|
|
+ OHUSB_RECIPIENT_INTERFACE = 0x01,
|
|
+
|
|
+ /** Endpoint */
|
|
+ OHUSB_RECIPIENT_ENDPOINT = 0x02,
|
|
+
|
|
+ /** Other */
|
|
+ OHUSB_RECIPIENT_OTHER = 0x03
|
|
+} ohusb_request_recipient;
|
|
+
|
|
+/*
|
|
+ * Standard requests
|
|
+ */
|
|
+typedef enum {
|
|
+ /** Request status of the specific recipient */
|
|
+ OHUSB_REQUEST_GET_STATUS = 0x00,
|
|
+
|
|
+ /** Clear or disable a specific feature */
|
|
+ OHUSB_REQUEST_CLEAR_FEATURE = 0x01,
|
|
+
|
|
+ /* 0x02 is reserved */
|
|
+
|
|
+ /** Set or enable a specific feature */
|
|
+ OHUSB_REQUEST_SET_FEATURE = 0x03,
|
|
+
|
|
+ /* 0x04 is reserved */
|
|
+
|
|
+ /** Set device address for all future accesses */
|
|
+ OHUSB_REQUEST_SET_ADDRESS = 0x05,
|
|
+
|
|
+ /** Get the specified descriptor */
|
|
+ OHUSB_REQUEST_GET_DESCRIPTOR = 0x06,
|
|
+
|
|
+ /** Used to update existing descriptors or add new descriptors */
|
|
+ OHUSB_REQUEST_SET_DESCRIPTOR = 0x07,
|
|
+
|
|
+ /** Get the current device configuration value */
|
|
+ OHUSB_REQUEST_GET_CONFIGURATION = 0x08,
|
|
+
|
|
+ /** Set device configuration */
|
|
+ OHUSB_REQUEST_SET_CONFIGURATION = 0x09,
|
|
+
|
|
+ /** Return the selected alternate setting for the specified interface */
|
|
+ OHUSB_REQUEST_GET_INTERFACE = 0x0a,
|
|
+
|
|
+ /** Select an alternate interface for the specified interface */
|
|
+ OHUSB_REQUEST_SET_INTERFACE = 0x0b,
|
|
+
|
|
+ /** Set then report an endpoint's synchronization frame */
|
|
+ OHUSB_REQUEST_SYNCH_FRAME = 0x0c,
|
|
+
|
|
+ /** Sets both the U1 and U2 Exit Latency */
|
|
+ OHUSB_REQUEST_SET_SEL = 0x30,
|
|
+
|
|
+ /** Delay from the time a host transmits a packet to the time it is
|
|
+ * received by the device. */
|
|
+ OHUSB_SET_ISOCH_DELAY = 0x31
|
|
+} ohusb_standard_request;
|
|
+
|
|
+/*
|
|
+ * Descriptor types as defined by the USB specification.
|
|
+ */
|
|
+typedef enum {
|
|
+ /** Device descriptor */
|
|
+ OHUSB_DT_DEVICE = 0x01,
|
|
+
|
|
+ /** Configuration descriptor */
|
|
+ OHUSB_DT_CONFIG = 0x02,
|
|
+
|
|
+ /** String descriptor */
|
|
+ OHUSB_DT_STRING = 0x03,
|
|
+
|
|
+ /** Interface descriptor */
|
|
+ OHUSB_DT_INTERFACE = 0x04,
|
|
+
|
|
+ /** Endpoint descriptor */
|
|
+ OHUSB_DT_ENDPOINT = 0x05,
|
|
+
|
|
+ /** Interface Association Descriptor */
|
|
+ OHUSB_DT_INTERFACE_ASSOCIATION = 0x0b,
|
|
+
|
|
+ /** BOS descriptor */
|
|
+ OHUSB_DT_BOS = 0x0f,
|
|
+
|
|
+ /** Device Capability descriptor */
|
|
+ OHUSB_DT_DEVICE_CAPABILITY = 0x10,
|
|
+
|
|
+ /** HID descriptor */
|
|
+ OHUSB_DT_HID = 0x21,
|
|
+
|
|
+ /** HID report descriptor */
|
|
+ OHUSB_DT_REPORT = 0x22,
|
|
+
|
|
+ /** Physical descriptor */
|
|
+ OHUSB_DT_PHYSICAL = 0x23,
|
|
+
|
|
+ /** Hub descriptor */
|
|
+ OHUSB_DT_HUB = 0x29,
|
|
+
|
|
+ /** SuperSpeed Hub descriptor */
|
|
+ OHUSB_DT_SUPERSPEED_HUB = 0x2a,
|
|
+
|
|
+ /** SuperSpeed Endpoint Companion descriptor */
|
|
+ OHUSB_DT_SS_ENDPOINT_COMPANION = 0x30
|
|
+} ohusb_descriptor_type;
|
|
+
|
|
+/**
|
|
+ * Error codes.
|
|
+ */
|
|
+typedef enum {
|
|
+ /** Success (no error) */
|
|
+ OHUSB_SUCCESS = 0,
|
|
+
|
|
+ /** Input/output error */
|
|
+ OHUSB_ERROR_IO = -1,
|
|
+
|
|
+ /** Invalid parameter */
|
|
+ OHUSB_ERROR_INVALID_PARAM = -2,
|
|
+
|
|
+ /** Access denied (insufficient permissions) */
|
|
+ OHUSB_ERROR_ACCESS = -3,
|
|
+
|
|
+ /** No such device (it may have been disconnected) */
|
|
+ OHUSB_ERROR_NO_DEVICE = -4,
|
|
+
|
|
+ /** Entity not found */
|
|
+ OHUSB_ERROR_NOT_FOUND = -5,
|
|
+
|
|
+ /** Resource busy */
|
|
+ OHUSB_ERROR_BUSY = -6,
|
|
+
|
|
+ /** Operation timed out */
|
|
+ OHUSB_ERROR_TIMEOUT = -7,
|
|
+
|
|
+ /** Overflow */
|
|
+ OHUSB_ERROR_OVERFLOW = -8,
|
|
+
|
|
+ /** Pipe error */
|
|
+ OHUSB_ERROR_PIPE = -9,
|
|
+
|
|
+ /** System call interrupted (perhaps due to signal) */
|
|
+ OHUSB_ERROR_INTERRUPTED = -10,
|
|
+
|
|
+ /** Insufficient memory */
|
|
+ OHUSB_ERROR_NO_MEM = -11,
|
|
+
|
|
+ /** Operation not supported or unimplemented on this platform */
|
|
+ OHUSB_ERROR_NOT_SUPPORTED = -12,
|
|
+
|
|
+ /** Other error */
|
|
+ OHUSB_ERROR_OTHER = -99
|
|
+} ohusb_error;
|
|
+
|
|
+/**
|
|
+ * A structure representing the parameter for usb control transfer.
|
|
+ */
|
|
+typedef struct {
|
|
+ /** Request type */
|
|
+ int32_t requestType;
|
|
+
|
|
+ /** Request */
|
|
+ int32_t request;
|
|
+
|
|
+ /** Value. Varies according to request */
|
|
+ int32_t value;
|
|
+
|
|
+ /** Index. Varies according to request, typically used to pass an index
|
|
+ * or offset */
|
|
+ int32_t index;
|
|
+
|
|
+ /** timeout */
|
|
+ int32_t timeout;
|
|
+} ohusb_control_transfer_parameter;
|
|
+
|
|
+/**
|
|
+ * A structure representing the standard USB endpoint descriptor.
|
|
+ */
|
|
+typedef struct {
|
|
+ /** Descriptor type */
|
|
+ uint8_t bDescriptorType;
|
|
+
|
|
+ /** The address of the endpoint described by this descriptor. Bits 0:3 are
|
|
+ * the endpoint number. Bits 4:6 are reserved. Bit 7 indicates direction. */
|
|
+ uint8_t bEndpointAddress;
|
|
+
|
|
+ /** Attributes which apply to the endpoint when it is configured using
|
|
+ * the bConfigurationValue. Bits 0:1 determine the transfer type. Bits 2:3 are
|
|
+ * only used for isochronous endpoints. Bits 4:5 are also only used for
|
|
+ * isochronous endpoints . Bits 6:7 are reserved. */
|
|
+ uint8_t bmAttributes;
|
|
+
|
|
+ /** Maximum packet size this endpoint is capable of sending/receiving. */
|
|
+ uint16_t wMaxPacketSize;
|
|
+
|
|
+ /** Interval for polling endpoint for data transfers. */
|
|
+ uint8_t bInterval;
|
|
+
|
|
+ /** The interface id the endpoint belongs to. */
|
|
+ uint8_t bInterfaceId;
|
|
+
|
|
+ /** The direction of the endpoint. */
|
|
+ uint32_t direction;
|
|
+} ohusb_endpoint_descriptor;
|
|
+
|
|
+/**
|
|
+ * A structure representing the standard USB interface descriptor.
|
|
+ */
|
|
+typedef struct {
|
|
+ /** Number of this interface */
|
|
+ uint8_t bInterfaceNumber;
|
|
+
|
|
+ /** Value used to select this alternate setting for this interface */
|
|
+ uint8_t bAlternateSetting;
|
|
+
|
|
+ /** USB-IF class code for this interface. */
|
|
+ uint8_t bInterfaceClass;
|
|
+
|
|
+ /** USB-IF subclass code for this interface, qualified by the
|
|
+ * bInterfaceClass value */
|
|
+ uint8_t bInterfaceSubClass;
|
|
+
|
|
+ /** USB-IF protocol code for this interface, qualified by the
|
|
+ * bInterfaceClass and bInterfaceSubClass values */
|
|
+ uint8_t bInterfaceProtocol;
|
|
+
|
|
+ /** Array of endpoint descriptors. This length of this array is determined
|
|
+ * by the bNumEndpoints field. */
|
|
+ ohusb_endpoint_descriptor *endpoint;
|
|
+
|
|
+ /** Number of endpoints used by this interface (excluding the control
|
|
+ * endpoint). */
|
|
+ uint8_t bNumEndpoints;
|
|
+} ohusb_interface_descriptor;
|
|
+
|
|
+/**
|
|
+ * A collection of alternate settings for a particular USB interface.
|
|
+ */
|
|
+typedef struct {
|
|
+ /** Array of interface descriptors. The length of this array is determined
|
|
+ * by the num_altsetting field. */
|
|
+ ohusb_interface_descriptor *altsetting;
|
|
+
|
|
+ /** The number of alternate settings that belong to this interface.
|
|
+ * Must be non-negative. */
|
|
+ int num_altsetting;
|
|
+} ohusb_interface;
|
|
+
|
|
+/**
|
|
+ * A structure representing the standard USB configuration descriptor.
|
|
+ */
|
|
+typedef struct {
|
|
+ /** Identifier value for this configuration */
|
|
+ uint8_t iConfiguration;
|
|
+
|
|
+ /** Configuration characteristics */
|
|
+ uint8_t bmAttributes;
|
|
+
|
|
+ /** Maximum power consumption of the USB device from this bus in this
|
|
+ * configuration when the device is fully operation. Expressed in units
|
|
+ * of 2 mA when the device is operating in high-speed mode and in units
|
|
+ * of 8 mA when the device is operating in super-speed mode. */
|
|
+ uint8_t MaxPower;
|
|
+
|
|
+ /** Array of interfaces supported by this configuration. The length of
|
|
+ * this array is determined by the bNumInterfaces field. */
|
|
+ ohusb_interface *interface;
|
|
+
|
|
+ /** Number of interfaces supported by this configuration */
|
|
+ uint8_t bNumInterfaces;
|
|
+} ohusb_config_descriptor;
|
|
+
|
|
+/**
|
|
+ * A structure representing the standard USB device descriptor.
|
|
+ */
|
|
+typedef struct {
|
|
+ /** The bus num of the usb device. */
|
|
+ uint8_t busNum;
|
|
+
|
|
+ /** The device address of the usb device. */
|
|
+ uint8_t devAddr;
|
|
+
|
|
+ /** USB specification release number in binary-coded decimal. A value of
|
|
+ * 0x0200 indicates USB 2.0, 0x0110 indicates USB 1.1, etc. */
|
|
+ uint16_t bcdUSB;
|
|
+
|
|
+ /** USB-IF class code for the device. */
|
|
+ uint8_t bDeviceClass;
|
|
+
|
|
+ /** USB-IF subclass code for the device, qualified by the bDeviceClass
|
|
+ * value */
|
|
+ uint8_t bDeviceSubClass;
|
|
+
|
|
+ /** USB-IF protocol code for the device, qualified by the bDeviceClass and
|
|
+ * bDeviceSubClass values */
|
|
+ uint8_t bDeviceProtocol;
|
|
+
|
|
+ /** Maximum packet size for endpoint 0 */
|
|
+ uint8_t bMaxPacketSize0;
|
|
+
|
|
+ /** USB-IF vendor ID */
|
|
+ uint16_t idVendor;
|
|
+
|
|
+ /** USB-IF product ID */
|
|
+ uint16_t idProduct;
|
|
+
|
|
+ /** Device release number in binary-coded decimal */
|
|
+ uint16_t bcdDevice;
|
|
+
|
|
+ /** Index of string descriptor describing manufacturer */
|
|
+ uint8_t iManufacturer;
|
|
+
|
|
+ /** Index of string descriptor describing product */
|
|
+ uint8_t iProduct;
|
|
+
|
|
+ /** Index of string descriptor containing device serial number */
|
|
+ uint8_t iSerialNumber;
|
|
+
|
|
+ /** Array of configs supported by this device. The length of
|
|
+ * this array is determined by the bNumConfigurations field. */
|
|
+ ohusb_config_descriptor *config;
|
|
+
|
|
+ /** Number of configs supported by this device */
|
|
+ uint8_t bNumConfigurations;
|
|
+} ohusb_device_descriptor;
|
|
+
|
|
+/**
|
|
+ * A structure representing the pipe information to transfer data.
|
|
+ */
|
|
+typedef struct {
|
|
+ /** The bus num of the usb device. */
|
|
+ uint8_t busNum;
|
|
+
|
|
+ /** The device address of the usb device. */
|
|
+ uint8_t devAddr;
|
|
+} ohusb_pipe;
|
|
+
|
|
+/**
|
|
+ * A structure representing the endpoint information to transfer data.
|
|
+ */
|
|
+typedef struct {
|
|
+ /** The interface id to which the endpoint to transmit data belongs. */
|
|
+ uint8_t bInterfaceId;
|
|
+
|
|
+ /** The endpoint address to transfer data. */
|
|
+ uint8_t bEndpointAddress;
|
|
+} ohusb_transfer_pipe;
|
|
+
|
|
+extern int32_t OH_GetDevices(ohusb_device_descriptor** list, ssize_t *numdevs);
|
|
+extern int32_t OH_OpenDevice(ohusb_device_descriptor *devDesc, ohusb_pipe **pipe);
|
|
+extern int32_t OH_CloseDevice(ohusb_pipe *pipe);
|
|
+extern int32_t OH_ClaimInterface(ohusb_pipe *pipe, int interfaceId, bool force);
|
|
+extern int32_t OH_ReleaseInterface(ohusb_pipe *pipe, int interfaceId);
|
|
+extern int32_t OH_BulkTransferRead(
|
|
+ ohusb_pipe *pipe, ohusb_transfer_pipe *tpipe, unsigned char *data, int length, int *transferred);
|
|
+extern int32_t OH_BulkTransferWrite(
|
|
+ ohusb_pipe *pipe, ohusb_transfer_pipe *tpipe, unsigned char *data, int length, int *transferred, int32_t timeout);
|
|
+extern int32_t OH_ControlTransferRead(
|
|
+ ohusb_pipe *pipe, ohusb_control_transfer_parameter *ctrlParam, unsigned char *data, uint16_t length);
|
|
+extern int32_t OH_ControlTransferWrite(
|
|
+ ohusb_pipe *pipe, ohusb_control_transfer_parameter *ctrlParam, unsigned char *data, uint16_t length);
|
|
+extern int32_t OH_GetStringDescriptor(ohusb_pipe *pipe, int descId, unsigned char *descriptor, int length);
|
|
+extern int32_t OH_SetConfiguration(ohusb_pipe *pipe, int configIndex);
|
|
+extern int32_t OH_SetInterface(ohusb_pipe *pipe, int interfaceId, int altIndex);
|
|
+
|
|
+#ifdef __cplusplus
|
|
+} // extern "C"
|
|
+#endif
|
|
+
|
|
+#endif /* USB_MANAGER_H */
|
|
\ No newline at end of file
|