Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(279)

Side by Side Diff: device/usb/usb_device_impl.cc

Issue 1265833005: Get all the UsbConfigDescriptor for the device configuration (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: updated code to continue instead of return if error happens when getting config descriptor Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "device/usb/usb_device_impl.h" 5 #include "device/usb/usb_device_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/location.h" 10 #include "base/location.h"
11 #include "base/sequenced_task_runner.h" 11 #include "base/sequenced_task_runner.h"
12 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/thread_task_runner_handle.h" 14 #include "base/thread_task_runner_handle.h"
15 #include "components/device_event_log/device_event_log.h" 15 #include "components/device_event_log/device_event_log.h"
16 #include "device/usb/usb_context.h" 16 #include "device/usb/usb_context.h"
17 #include "device/usb/usb_descriptors.h"
18 #include "device/usb/usb_device_handle_impl.h" 17 #include "device/usb/usb_device_handle_impl.h"
19 #include "device/usb/usb_error.h" 18 #include "device/usb/usb_error.h"
20 #include "third_party/libusb/src/libusb/libusb.h" 19 #include "third_party/libusb/src/libusb/libusb.h"
21 20
22 #if defined(OS_CHROMEOS) 21 #if defined(OS_CHROMEOS)
23 #include "chromeos/dbus/dbus_thread_manager.h" 22 #include "chromeos/dbus/dbus_thread_manager.h"
24 #include "chromeos/dbus/permission_broker_client.h" 23 #include "chromeos/dbus/permission_broker_client.h"
25 #include "dbus/file_descriptor.h" 24 #include "dbus/file_descriptor.h"
26 #endif // defined(OS_CHROMEOS) 25 #endif // defined(OS_CHROMEOS)
27 26
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 case LIBUSB_ISO_USAGE_TYPE_FEEDBACK: 81 case LIBUSB_ISO_USAGE_TYPE_FEEDBACK:
83 return USB_USAGE_FEEDBACK; 82 return USB_USAGE_FEEDBACK;
84 case LIBUSB_ISO_USAGE_TYPE_IMPLICIT: 83 case LIBUSB_ISO_USAGE_TYPE_IMPLICIT:
85 return USB_USAGE_EXPLICIT_FEEDBACK; 84 return USB_USAGE_EXPLICIT_FEEDBACK;
86 default: 85 default:
87 NOTREACHED(); 86 NOTREACHED();
88 return USB_USAGE_DATA; 87 return USB_USAGE_DATA;
89 } 88 }
90 } 89 }
91 90
91 void SetConfigDescriptor(const libusb_config_descriptor* platform_config,
Reilly Grant (use Gerrit) 2015/08/03 18:04:04 I suggest renaming this to "ConvertConfigDescripto
juncai 2015/08/03 21:56:25 Done.
92 UsbConfigDescriptor* configuration) {
93 configuration->configuration_value = platform_config->bConfigurationValue;
94 configuration->self_powered = (platform_config->bmAttributes & 0x40) != 0;
95 configuration->remote_wakeup = (platform_config->bmAttributes & 0x20) != 0;
96 configuration->maximum_power = platform_config->MaxPower * 2;
97
98 for (size_t i = 0; i < platform_config->bNumInterfaces; ++i) {
99 const struct libusb_interface* platform_interface =
100 &platform_config->interface[i];
101 for (int j = 0; j < platform_interface->num_altsetting; ++j) {
102 const struct libusb_interface_descriptor* platform_alt_setting =
103 &platform_interface->altsetting[j];
104 UsbInterfaceDescriptor interface;
105
106 interface.interface_number = platform_alt_setting->bInterfaceNumber;
107 interface.alternate_setting = platform_alt_setting->bAlternateSetting;
108 interface.interface_class = platform_alt_setting->bInterfaceClass;
109 interface.interface_subclass = platform_alt_setting->bInterfaceSubClass;
110 interface.interface_protocol = platform_alt_setting->bInterfaceProtocol;
111
112 for (size_t k = 0; k < platform_alt_setting->bNumEndpoints; ++k) {
113 const struct libusb_endpoint_descriptor* platform_endpoint =
114 &platform_alt_setting->endpoint[k];
115 UsbEndpointDescriptor endpoint;
116
117 endpoint.address = platform_endpoint->bEndpointAddress;
118 endpoint.direction = GetDirection(platform_endpoint);
119 endpoint.maximum_packet_size = platform_endpoint->wMaxPacketSize;
120 endpoint.synchronization_type =
121 GetSynchronizationType(platform_endpoint);
122 endpoint.transfer_type = GetTransferType(platform_endpoint);
123 endpoint.usage_type = GetUsageType(platform_endpoint);
124 endpoint.polling_interval = platform_endpoint->bInterval;
125 endpoint.extra_data = std::vector<uint8_t>(
126 platform_endpoint->extra,
127 platform_endpoint->extra + platform_endpoint->extra_length);
128
129 interface.endpoints.push_back(endpoint);
130 }
131
132 interface.extra_data = std::vector<uint8_t>(
133 platform_alt_setting->extra,
134 platform_alt_setting->extra + platform_alt_setting->extra_length);
135
136 configuration->interfaces.push_back(interface);
137 }
138 }
139
140 configuration->extra_data = std::vector<uint8_t>(
141 platform_config->extra,
142 platform_config->extra + platform_config->extra_length);
143 }
144
92 } // namespace 145 } // namespace
93 146
94 UsbDeviceImpl::UsbDeviceImpl( 147 UsbDeviceImpl::UsbDeviceImpl(
95 scoped_refptr<UsbContext> context, 148 scoped_refptr<UsbContext> context,
96 PlatformUsbDevice platform_device, 149 PlatformUsbDevice platform_device,
97 uint16 vendor_id, 150 uint16 vendor_id,
98 uint16 product_id, 151 uint16 product_id,
99 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) 152 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
100 : UsbDevice(vendor_id, 153 : UsbDevice(vendor_id,
101 product_id, 154 product_id,
102 base::string16(), 155 base::string16(),
103 base::string16(), 156 base::string16(),
104 base::string16()), 157 base::string16()),
105 platform_device_(platform_device), 158 platform_device_(platform_device),
106 context_(context), 159 context_(context),
107 task_runner_(base::ThreadTaskRunnerHandle::Get()), 160 task_runner_(base::ThreadTaskRunnerHandle::Get()),
108 blocking_task_runner_(blocking_task_runner) { 161 blocking_task_runner_(blocking_task_runner) {
109 CHECK(platform_device) << "platform_device cannot be NULL"; 162 CHECK(platform_device) << "platform_device cannot be NULL";
110 libusb_ref_device(platform_device); 163 libusb_ref_device(platform_device);
164 set_configurations();
Reilly Grant (use Gerrit) 2015/08/03 18:04:04 This function is non-trivial and so cannot use thi
juncai 2015/08/03 21:56:25 Done.
111 RefreshConfiguration(); 165 RefreshConfiguration();
Reilly Grant (use Gerrit) 2015/08/03 18:04:04 I suggest renaming this to "RefreshActiveConfigura
juncai 2015/08/03 21:56:25 Done.
112 } 166 }
113 167
114 UsbDeviceImpl::~UsbDeviceImpl() { 168 UsbDeviceImpl::~UsbDeviceImpl() {
115 // The destructor must be safe to call from any thread. 169 // The destructor must be safe to call from any thread.
116 libusb_unref_device(platform_device_); 170 libusb_unref_device(platform_device_);
117 } 171 }
118 172
119 #if defined(OS_CHROMEOS) 173 #if defined(OS_CHROMEOS)
120 174
121 void UsbDeviceImpl::CheckUsbAccess(const ResultCallback& callback) { 175 void UsbDeviceImpl::CheckUsbAccess(const ResultCallback& callback) {
(...skipping 30 matching lines...) Expand all
152 ++it) { 206 ++it) {
153 if (it->get() == handle.get()) { 207 if (it->get() == handle.get()) {
154 (*it)->InternalClose(); 208 (*it)->InternalClose();
155 handles_.erase(it); 209 handles_.erase(it);
156 return true; 210 return true;
157 } 211 }
158 } 212 }
159 return false; 213 return false;
160 } 214 }
161 215
162 const UsbConfigDescriptor* UsbDeviceImpl::GetConfiguration() { 216 const UsbConfigDescriptor* UsbDeviceImpl::GetActiveConfiguration() {
163 DCHECK(thread_checker_.CalledOnValidThread()); 217 DCHECK(thread_checker_.CalledOnValidThread());
164 return configuration_.get(); 218 return configuration_;
165 } 219 }
166 220
167 void UsbDeviceImpl::OnDisconnect() { 221 void UsbDeviceImpl::OnDisconnect() {
168 DCHECK(thread_checker_.CalledOnValidThread()); 222 DCHECK(thread_checker_.CalledOnValidThread());
169 223
170 // Swap the list of handles into a local variable because closing all open 224 // Swap the list of handles into a local variable because closing all open
171 // handles may release the last reference to this object. 225 // handles may release the last reference to this object.
172 HandlesVector handles; 226 HandlesVector handles;
173 swap(handles, handles_); 227 swap(handles, handles_);
174 228
175 for (const scoped_refptr<UsbDeviceHandleImpl>& handle : handles_) { 229 for (const scoped_refptr<UsbDeviceHandleImpl>& handle : handles_) {
176 handle->InternalClose(); 230 handle->InternalClose();
177 } 231 }
178 } 232 }
179 233
234 void UsbDeviceImpl::set_configurations() {
235 libusb_device_descriptor device_descriptor;
236 int rv = libusb_get_device_descriptor(platform_device_, &device_descriptor);
237 if (rv == LIBUSB_SUCCESS) {
238 uint8_t num_configurations = device_descriptor.bNumConfigurations;
239 configurations_.reserve(num_configurations);
240 for (uint8_t i = 0; i < num_configurations; i++) {
241 libusb_config_descriptor* platform_config;
242 rv = libusb_get_config_descriptor(platform_device_, i, &platform_config);
243 if (rv != LIBUSB_SUCCESS) {
244 USB_LOG(EVENT) << "Failed to get config descriptor: "
245 << ConvertPlatformUsbErrorToString(rv);
246 continue;
247 }
248
249 UsbConfigDescriptor config_descriptor;
250 SetConfigDescriptor(platform_config, &config_descriptor);
251 configurations_.push_back(config_descriptor);
252 libusb_free_config_descriptor(platform_config);
253 }
254 } else {
255 USB_LOG(EVENT) << "Failed to get device descriptor: "
256 << ConvertPlatformUsbErrorToString(rv);
257 }
258 }
259
180 void UsbDeviceImpl::RefreshConfiguration() { 260 void UsbDeviceImpl::RefreshConfiguration() {
181 libusb_config_descriptor* platform_config; 261 libusb_config_descriptor* platform_config;
182 int rv = 262 int rv =
183 libusb_get_active_config_descriptor(platform_device_, &platform_config); 263 libusb_get_active_config_descriptor(platform_device_, &platform_config);
184 if (rv != LIBUSB_SUCCESS) { 264 if (rv != LIBUSB_SUCCESS) {
185 USB_LOG(EVENT) << "Failed to get config descriptor: " 265 USB_LOG(EVENT) << "Failed to get config descriptor: "
186 << ConvertPlatformUsbErrorToString(rv); 266 << ConvertPlatformUsbErrorToString(rv);
187 return; 267 return;
188 } 268 }
189 269
190 configuration_.reset(new UsbConfigDescriptor()); 270 configuration_ = nullptr;
191 configuration_->configuration_value = platform_config->bConfigurationValue; 271 size_t num_configurations = configurations_.size();
192 configuration_->self_powered = (platform_config->bmAttributes & 0x40) != 0; 272 for (size_t i = 0; i < num_configurations; ++i) {
193 configuration_->remote_wakeup = (platform_config->bmAttributes & 0x20) != 0; 273 if (configurations_[i].configuration_value ==
194 configuration_->maximum_power = platform_config->MaxPower * 2; 274 platform_config->bConfigurationValue) {
195 275 configuration_ = &configurations_[i];
196 for (size_t i = 0; i < platform_config->bNumInterfaces; ++i) { 276 break;
197 const struct libusb_interface* platform_interface =
198 &platform_config->interface[i];
199 for (int j = 0; j < platform_interface->num_altsetting; ++j) {
200 const struct libusb_interface_descriptor* platform_alt_setting =
201 &platform_interface->altsetting[j];
202 UsbInterfaceDescriptor interface;
203
204 interface.interface_number = platform_alt_setting->bInterfaceNumber;
205 interface.alternate_setting = platform_alt_setting->bAlternateSetting;
206 interface.interface_class = platform_alt_setting->bInterfaceClass;
207 interface.interface_subclass = platform_alt_setting->bInterfaceSubClass;
208 interface.interface_protocol = platform_alt_setting->bInterfaceProtocol;
209
210 for (size_t k = 0; k < platform_alt_setting->bNumEndpoints; ++k) {
211 const struct libusb_endpoint_descriptor* platform_endpoint =
212 &platform_alt_setting->endpoint[k];
213 UsbEndpointDescriptor endpoint;
214
215 endpoint.address = platform_endpoint->bEndpointAddress;
216 endpoint.direction = GetDirection(platform_endpoint);
217 endpoint.maximum_packet_size = platform_endpoint->wMaxPacketSize;
218 endpoint.synchronization_type =
219 GetSynchronizationType(platform_endpoint);
220 endpoint.transfer_type = GetTransferType(platform_endpoint);
221 endpoint.usage_type = GetUsageType(platform_endpoint);
222 endpoint.polling_interval = platform_endpoint->bInterval;
223 endpoint.extra_data = std::vector<uint8_t>(
224 platform_endpoint->extra,
225 platform_endpoint->extra + platform_endpoint->extra_length);
226
227 interface.endpoints.push_back(endpoint);
228 }
229
230 interface.extra_data = std::vector<uint8_t>(
231 platform_alt_setting->extra,
232 platform_alt_setting->extra + platform_alt_setting->extra_length);
233
234 configuration_->interfaces.push_back(interface);
235 } 277 }
236 } 278 }
237 279
238 configuration_->extra_data = std::vector<uint8_t>(
239 platform_config->extra,
240 platform_config->extra + platform_config->extra_length);
241
242 libusb_free_config_descriptor(platform_config); 280 libusb_free_config_descriptor(platform_config);
243 } 281 }
244 282
245 #if defined(OS_CHROMEOS) 283 #if defined(OS_CHROMEOS)
246 284
247 void UsbDeviceImpl::OnOpenRequestComplete(const OpenCallback& callback, 285 void UsbDeviceImpl::OnOpenRequestComplete(const OpenCallback& callback,
248 dbus::FileDescriptor fd) { 286 dbus::FileDescriptor fd) {
249 blocking_task_runner_->PostTask( 287 blocking_task_runner_->PostTask(
250 FROM_HERE, base::Bind(&UsbDeviceImpl::OpenOnBlockingThreadWithFd, this, 288 FROM_HERE, base::Bind(&UsbDeviceImpl::OpenOnBlockingThreadWithFd, this,
251 base::Passed(&fd), callback)); 289 base::Passed(&fd), callback));
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 void UsbDeviceImpl::Opened(PlatformUsbDeviceHandle platform_handle, 328 void UsbDeviceImpl::Opened(PlatformUsbDeviceHandle platform_handle,
291 const OpenCallback& callback) { 329 const OpenCallback& callback) {
292 DCHECK(thread_checker_.CalledOnValidThread()); 330 DCHECK(thread_checker_.CalledOnValidThread());
293 scoped_refptr<UsbDeviceHandleImpl> device_handle = new UsbDeviceHandleImpl( 331 scoped_refptr<UsbDeviceHandleImpl> device_handle = new UsbDeviceHandleImpl(
294 context_, this, platform_handle, blocking_task_runner_); 332 context_, this, platform_handle, blocking_task_runner_);
295 handles_.push_back(device_handle); 333 handles_.push_back(device_handle);
296 callback.Run(device_handle); 334 callback.Run(device_handle);
297 } 335 }
298 336
299 } // namespace device 337 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698