diff --git a/services/native/include/usb_descriptor_parser.h b/services/native/include/usb_descriptor_parser.h index a9a5276db1d724922edc359414736bb0d4b8cf23..0bb593f8a66d8bdede3675a78fb5453ec2f0b9a3 100644 --- a/services/native/include/usb_descriptor_parser.h +++ b/services/native/include/usb_descriptor_parser.h @@ -25,6 +25,8 @@ public: ~UsbDescriptorParser(); static int32_t ParseDeviceDescriptor(const uint8_t *buffer, uint32_t length, UsbDevice &dev); + static int32_t ParseConfigDescriptors(std::vector &descriptor, uint32_t offset, + std::vector &configs); static int32_t ParseConfigDescriptor(const uint8_t *buffer, uint32_t length, uint32_t &cursor, USBConfig &config); static int32_t ParseInterfaceDescriptor(const uint8_t *buffer, uint32_t length, uint32_t &cursor, UsbInterface &interface); diff --git a/services/native/src/usb_descriptor_parser.cpp b/services/native/src/usb_descriptor_parser.cpp index cb8e3c8312cca55b6297140485b32f4619d0540f..3cdd8a611263b352d5a8a36386988d76d07c5f3c 100644 --- a/services/native/src/usb_descriptor_parser.cpp +++ b/services/native/src/usb_descriptor_parser.cpp @@ -73,6 +73,121 @@ int32_t UsbDescriptorParser::ParseDeviceDescriptor(const uint8_t *buffer, uint32 return UEC_OK; } +static int32_t AddConfig(std::vector &configs, const UsbdConfigDescriptor *configDescriptor) +{ + if (configDescriptor == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "configDescriptor is nullptr"); + return UEC_SERVICE_INVALID_VALUE; + } + + USBConfig config; + config.SetId(configDescriptor->bConfigurationValue); + config.SetAttribute(configDescriptor->bmAttributes); + config.SetMaxPower(configDescriptor->bMaxPower); + config.SetiConfiguration(configDescriptor->iConfiguration); + configs.emplace_back(config); + USB_HILOGD(MODULE_USB_SERVICE, "add config, interfaces=%{public}u", configDescriptor->bNumInterfaces); + return UEC_OK; +} + +static int32_t AddInterface(std::vector &configs, const UsbdInterfaceDescriptor *interfaceDescriptor) +{ + if (interfaceDescriptor == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "interfaceDescriptor is nullptr"); + return UEC_SERVICE_INVALID_VALUE; + } + if (configs.empty()) { + USB_HILOGE(MODULE_USB_SERVICE, "config descriptor not found"); + return UEC_SERVICE_INVALID_VALUE; + } + + UsbInterface interface; + interface.SetId(interfaceDescriptor->bInterfaceNumber); + interface.SetProtocol(interfaceDescriptor->bInterfaceProtocol); + interface.SetAlternateSetting(interfaceDescriptor->bAlternateSetting); + interface.SetClass(interfaceDescriptor->bInterfaceClass); + interface.SetSubClass(interfaceDescriptor->bInterfaceSubClass); + interface.SetiInterface(interfaceDescriptor->iInterface); + configs.back().GetInterfaces().emplace_back(interface); + USB_HILOGD(MODULE_USB_SERVICE, "add interface, endpoints=%{public}u", interfaceDescriptor->bNumEndpoints); + return UEC_OK; +} + +static int32_t AddEndpoint(std::vector &configs, const UsbdEndpointDescriptor *endpointDescriptor) +{ + if (endpointDescriptor == nullptr) { + USB_HILOGE(MODULE_USB_SERVICE, "endpointDescriptor is nullptr"); + return UEC_SERVICE_INVALID_VALUE; + } + if (configs.empty() || configs.back().GetInterfaces().empty()) { + USB_HILOGE(MODULE_USB_SERVICE, "interface descriptor not found"); + return UEC_SERVICE_INVALID_VALUE; + } + + USBEndpoint endpoint; + endpoint.SetAddr(endpointDescriptor->bEndpointAddress); + endpoint.SetAttr(endpointDescriptor->bmAttributes); + endpoint.SetInterval(endpointDescriptor->bInterval); + endpoint.SetMaxPacketSize(endpointDescriptor->wMaxPacketSize); + endpoint.SetInterfaceId(configs.back().GetInterfaces().back().GetId()); + configs.back().GetInterfaces().back().GetEndpoints().emplace_back(endpoint); + USB_HILOGD(MODULE_USB_SERVICE, "add endpoint, address=%{public}u", endpointDescriptor->bEndpointAddress); + return UEC_OK; +} + +int32_t UsbDescriptorParser::ParseConfigDescriptors(std::vector &descriptor, uint32_t offset, + std::vector &configs) +{ + uint8_t *buffer = descriptor.data(); + uint32_t length = descriptor.size(); + uint32_t cursor = offset; + int32_t ret = UEC_OK; + + while (cursor < length) { + if ((length - cursor) < sizeof(UsbdDescriptorHeader)) { + USB_HILOGW(MODULE_USB_SERVICE, "invalid desc data, length=%{public}u, cursor=%{public}u", length, cursor); + break; + } + UsbdDescriptorHeader descriptorHeader = *(reinterpret_cast(buffer + cursor)); + if (descriptorHeader.bLength > (length - cursor)) { + USB_HILOGW(MODULE_USB_SERVICE, "invalid data length, length=%{public}u, cursor=%{public}u", length, cursor); + break; + } + switch (descriptorHeader.bDescriptorType) { + case static_cast(DescriptorType::DESCRIPTOR_TYPE_CONFIG): + if (descriptorHeader.bLength != sizeof(UsbdConfigDescriptor)) { + USB_HILOGE(MODULE_USB_SERVICE, "invalid config, length=%{public}u", descriptorHeader.bLength); + return UEC_SERVICE_INVALID_VALUE; + } + ret = AddConfig(configs, reinterpret_cast(buffer + cursor)); + break; + case static_cast(DescriptorType::DESCRIPTOR_TYPE_INTERFACE): + if (descriptorHeader.bLength != sizeof(UsbdInterfaceDescriptor)) { + USB_HILOGE(MODULE_USB_SERVICE, "invalid interface, length=%{public}u", descriptorHeader.bLength); + return UEC_SERVICE_INVALID_VALUE; + } + ret = AddInterface(configs, reinterpret_cast(buffer + cursor)); + break; + case static_cast(DescriptorType::DESCRIPTOR_TYPE_ENDPOINT): + if (descriptorHeader.bLength != NORMAL_ENDPOINT_DESCRIPTOR + && descriptorHeader.bLength != AUDIO_ENDPOINT_DESCRIPTOR) { + USB_HILOGE(MODULE_USB_SERVICE, "invalid endpoint, length=%{public}u", descriptorHeader.bLength); + return UEC_SERVICE_INVALID_VALUE; + } + ret = AddEndpoint(configs, reinterpret_cast(buffer + cursor)); + break; + default: + USB_HILOGW(MODULE_USB_SERVICE, "unrecognized type=%{public}d", descriptorHeader.bDescriptorType); + break; + } + if (ret != UEC_OK) { + return ret; + } + cursor += descriptorHeader.bLength; + } + return ret; +} + int32_t UsbDescriptorParser::ParseConfigDescriptor( const uint8_t *buffer, uint32_t length, uint32_t &cursor, USBConfig &config) { diff --git a/services/native/src/usb_service.cpp b/services/native/src/usb_service.cpp index 810ae2f90d2e8e60aa2b62f94323e00c44a4bb3c..a558467ed4929cb6be26c57519df62936c3e3ff9 100644 --- a/services/native/src/usb_service.cpp +++ b/services/native/src/usb_service.cpp @@ -955,25 +955,10 @@ int32_t UsbService::GetDeviceInfoDescriptor(const UsbDev &uDev, std::vector &descriptor) { std::vector configs; - uint8_t *buffer = descriptor.data(); - uint32_t length = descriptor.size(); - uint32_t cursor = CURSOR_INIT; - int32_t ret = UEC_OK; - for (uint8_t i = 0; i < dev.GetDescConfigCount(); ++i) { - if (length <= cursor) { - USB_HILOGE(MODULE_USB_SERVICE, "GetConfigDescriptor[%{public}d] length=%{public}d", i, length); - break; - } - USB_HILOGI(MODULE_USB_SERVICE, "GetConfigDescriptor length=%{public}d", length); - uint32_t configCursor = 0; - USBConfig config; - ret = UsbDescriptorParser::ParseConfigDescriptor(buffer + cursor, length - cursor, configCursor, config); - if (ret != UEC_OK) { - USB_HILOGE(MODULE_USB_SERVICE, "ParseConfigDescriptor failed ret=%{public}d", ret); - return ret; - } - cursor += configCursor; - configs.push_back(config); + int32_t ret = UsbDescriptorParser::ParseConfigDescriptors(descriptor, CURSOR_INIT, configs); + if (ret != UEC_OK) { + USB_HILOGE(MODULE_USB_SERVICE, "ParseConfigDescriptors failed ret=%{public}d", ret); + return ret; } dev.SetConfigs(configs); ret = FillDevStrings(dev);