Index: device/usb/usb_device_impl.cc |
diff --git a/device/usb/usb_device_impl.cc b/device/usb/usb_device_impl.cc |
index 114e6acaa568fec23630556cd6347d1519aec033..e71e16ce2d78c72916c1b47bd3c1d46279c87c7a 100644 |
--- a/device/usb/usb_device_impl.cc |
+++ b/device/usb/usb_device_impl.cc |
@@ -89,6 +89,61 @@ UsbUsageType GetUsageType(const libusb_endpoint_descriptor* descriptor) { |
} |
} |
+void ConvertConfigDescriptor(const libusb_config_descriptor* platform_config, |
+ UsbConfigDescriptor* configuration) { |
+ configuration->configuration_value = platform_config->bConfigurationValue; |
+ configuration->self_powered = (platform_config->bmAttributes & 0x40) != 0; |
+ configuration->remote_wakeup = (platform_config->bmAttributes & 0x20) != 0; |
+ configuration->maximum_power = platform_config->MaxPower * 2; |
+ |
+ for (size_t i = 0; i < platform_config->bNumInterfaces; ++i) { |
+ const struct libusb_interface* platform_interface = |
+ &platform_config->interface[i]; |
+ for (int j = 0; j < platform_interface->num_altsetting; ++j) { |
+ const struct libusb_interface_descriptor* platform_alt_setting = |
+ &platform_interface->altsetting[j]; |
+ UsbInterfaceDescriptor interface; |
+ |
+ interface.interface_number = platform_alt_setting->bInterfaceNumber; |
+ interface.alternate_setting = platform_alt_setting->bAlternateSetting; |
+ interface.interface_class = platform_alt_setting->bInterfaceClass; |
+ interface.interface_subclass = platform_alt_setting->bInterfaceSubClass; |
+ interface.interface_protocol = platform_alt_setting->bInterfaceProtocol; |
+ |
+ interface.endpoints.reserve(platform_alt_setting->bNumEndpoints); |
+ for (size_t k = 0; k < platform_alt_setting->bNumEndpoints; ++k) { |
+ const struct libusb_endpoint_descriptor* platform_endpoint = |
+ &platform_alt_setting->endpoint[k]; |
+ UsbEndpointDescriptor endpoint; |
+ |
+ endpoint.address = platform_endpoint->bEndpointAddress; |
+ endpoint.direction = GetDirection(platform_endpoint); |
+ endpoint.maximum_packet_size = platform_endpoint->wMaxPacketSize; |
+ endpoint.synchronization_type = |
+ GetSynchronizationType(platform_endpoint); |
+ endpoint.transfer_type = GetTransferType(platform_endpoint); |
+ endpoint.usage_type = GetUsageType(platform_endpoint); |
+ endpoint.polling_interval = platform_endpoint->bInterval; |
+ endpoint.extra_data = std::vector<uint8_t>( |
+ platform_endpoint->extra, |
+ platform_endpoint->extra + platform_endpoint->extra_length); |
+ |
+ interface.endpoints.push_back(endpoint); |
+ } |
+ |
+ interface.extra_data = std::vector<uint8_t>( |
+ platform_alt_setting->extra, |
+ platform_alt_setting->extra + platform_alt_setting->extra_length); |
+ |
+ configuration->interfaces.push_back(interface); |
+ } |
+ } |
+ |
+ configuration->extra_data = std::vector<uint8_t>( |
+ platform_config->extra, |
+ platform_config->extra + platform_config->extra_length); |
+} |
+ |
} // namespace |
UsbDeviceImpl::UsbDeviceImpl( |
@@ -108,7 +163,8 @@ UsbDeviceImpl::UsbDeviceImpl( |
blocking_task_runner_(blocking_task_runner) { |
CHECK(platform_device) << "platform_device cannot be NULL"; |
libusb_ref_device(platform_device); |
- RefreshConfiguration(); |
+ ReadAllConfigurations(); |
+ RefreshActiveConfiguration(); |
} |
UsbDeviceImpl::~UsbDeviceImpl() { |
@@ -159,9 +215,9 @@ bool UsbDeviceImpl::Close(scoped_refptr<UsbDeviceHandle> handle) { |
return false; |
} |
-const UsbConfigDescriptor* UsbDeviceImpl::GetConfiguration() { |
+const UsbConfigDescriptor* UsbDeviceImpl::GetActiveConfiguration() { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- return configuration_.get(); |
+ return active_configuration_; |
} |
void UsbDeviceImpl::OnDisconnect() { |
@@ -177,7 +233,33 @@ void UsbDeviceImpl::OnDisconnect() { |
} |
} |
-void UsbDeviceImpl::RefreshConfiguration() { |
+void UsbDeviceImpl::ReadAllConfigurations() { |
+ libusb_device_descriptor device_descriptor; |
+ int rv = libusb_get_device_descriptor(platform_device_, &device_descriptor); |
+ if (rv == LIBUSB_SUCCESS) { |
+ uint8_t num_configurations = device_descriptor.bNumConfigurations; |
+ configurations_.reserve(num_configurations); |
+ for (uint8_t i = 0; i < num_configurations; ++i) { |
+ libusb_config_descriptor* platform_config; |
+ rv = libusb_get_config_descriptor(platform_device_, i, &platform_config); |
+ if (rv != LIBUSB_SUCCESS) { |
+ USB_LOG(EVENT) << "Failed to get config descriptor: " |
+ << ConvertPlatformUsbErrorToString(rv); |
+ continue; |
+ } |
+ |
+ UsbConfigDescriptor config_descriptor; |
+ ConvertConfigDescriptor(platform_config, &config_descriptor); |
+ configurations_.push_back(config_descriptor); |
+ libusb_free_config_descriptor(platform_config); |
+ } |
+ } else { |
+ USB_LOG(EVENT) << "Failed to get device descriptor: " |
+ << ConvertPlatformUsbErrorToString(rv); |
+ } |
+} |
+ |
+void UsbDeviceImpl::RefreshActiveConfiguration() { |
libusb_config_descriptor* platform_config; |
int rv = |
libusb_get_active_config_descriptor(platform_device_, &platform_config); |
@@ -187,58 +269,14 @@ void UsbDeviceImpl::RefreshConfiguration() { |
return; |
} |
- configuration_.reset(new UsbConfigDescriptor()); |
- configuration_->configuration_value = platform_config->bConfigurationValue; |
- configuration_->self_powered = (platform_config->bmAttributes & 0x40) != 0; |
- configuration_->remote_wakeup = (platform_config->bmAttributes & 0x20) != 0; |
- configuration_->maximum_power = platform_config->MaxPower * 2; |
- |
- for (size_t i = 0; i < platform_config->bNumInterfaces; ++i) { |
- const struct libusb_interface* platform_interface = |
- &platform_config->interface[i]; |
- for (int j = 0; j < platform_interface->num_altsetting; ++j) { |
- const struct libusb_interface_descriptor* platform_alt_setting = |
- &platform_interface->altsetting[j]; |
- UsbInterfaceDescriptor interface; |
- |
- interface.interface_number = platform_alt_setting->bInterfaceNumber; |
- interface.alternate_setting = platform_alt_setting->bAlternateSetting; |
- interface.interface_class = platform_alt_setting->bInterfaceClass; |
- interface.interface_subclass = platform_alt_setting->bInterfaceSubClass; |
- interface.interface_protocol = platform_alt_setting->bInterfaceProtocol; |
- |
- for (size_t k = 0; k < platform_alt_setting->bNumEndpoints; ++k) { |
- const struct libusb_endpoint_descriptor* platform_endpoint = |
- &platform_alt_setting->endpoint[k]; |
- UsbEndpointDescriptor endpoint; |
- |
- endpoint.address = platform_endpoint->bEndpointAddress; |
- endpoint.direction = GetDirection(platform_endpoint); |
- endpoint.maximum_packet_size = platform_endpoint->wMaxPacketSize; |
- endpoint.synchronization_type = |
- GetSynchronizationType(platform_endpoint); |
- endpoint.transfer_type = GetTransferType(platform_endpoint); |
- endpoint.usage_type = GetUsageType(platform_endpoint); |
- endpoint.polling_interval = platform_endpoint->bInterval; |
- endpoint.extra_data = std::vector<uint8_t>( |
- platform_endpoint->extra, |
- platform_endpoint->extra + platform_endpoint->extra_length); |
- |
- interface.endpoints.push_back(endpoint); |
- } |
- |
- interface.extra_data = std::vector<uint8_t>( |
- platform_alt_setting->extra, |
- platform_alt_setting->extra + platform_alt_setting->extra_length); |
- |
- configuration_->interfaces.push_back(interface); |
+ active_configuration_ = nullptr; |
+ for (const auto& config : configurations_) { |
+ if (config.configuration_value == platform_config->bConfigurationValue) { |
+ active_configuration_ = &config; |
+ break; |
} |
} |
- configuration_->extra_data = std::vector<uint8_t>( |
- platform_config->extra, |
- platform_config->extra + platform_config->extra_length); |
- |
libusb_free_config_descriptor(platform_config); |
} |