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

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

Issue 826283002: Add support for sending a USB SET_CONFIGURATION request. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 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"
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 117
118 UsbDeviceImpl::UsbDeviceImpl( 118 UsbDeviceImpl::UsbDeviceImpl(
119 scoped_refptr<UsbContext> context, 119 scoped_refptr<UsbContext> context,
120 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 120 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
121 PlatformUsbDevice platform_device, 121 PlatformUsbDevice platform_device,
122 uint16 vendor_id, 122 uint16 vendor_id,
123 uint16 product_id, 123 uint16 product_id,
124 uint32 unique_id) 124 uint32 unique_id)
125 : UsbDevice(vendor_id, product_id, unique_id), 125 : UsbDevice(vendor_id, product_id, unique_id),
126 platform_device_(platform_device), 126 platform_device_(platform_device),
127 current_configuration_cached_(false),
128 context_(context), 127 context_(context),
129 ui_task_runner_(ui_task_runner) { 128 ui_task_runner_(ui_task_runner) {
130 CHECK(platform_device) << "platform_device cannot be NULL"; 129 CHECK(platform_device) << "platform_device cannot be NULL";
131 libusb_ref_device(platform_device); 130 libusb_ref_device(platform_device);
132 131 RefreshConfiguration();
133 #if defined(USE_UDEV) 132 #if defined(USE_UDEV)
134 ScopedUdevPtr udev(udev_new()); 133 ScopedUdevPtr udev(udev_new());
135 ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev.get())); 134 ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev.get()));
136 135
137 udev_enumerate_add_match_subsystem(enumerate.get(), "usb"); 136 udev_enumerate_add_match_subsystem(enumerate.get(), "usb");
138 if (udev_enumerate_scan_devices(enumerate.get()) != 0) { 137 if (udev_enumerate_scan_devices(enumerate.get()) != 0) {
139 return; 138 return;
140 } 139 }
141 std::string bus_number = 140 std::string bus_number =
142 base::IntToString(libusb_get_bus_number(platform_device)); 141 base::IntToString(libusb_get_bus_number(platform_device));
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 } 225 }
227 } 226 }
228 227
229 #endif 228 #endif
230 229
231 scoped_refptr<UsbDeviceHandle> UsbDeviceImpl::Open() { 230 scoped_refptr<UsbDeviceHandle> UsbDeviceImpl::Open() {
232 DCHECK(thread_checker_.CalledOnValidThread()); 231 DCHECK(thread_checker_.CalledOnValidThread());
233 PlatformUsbDeviceHandle handle; 232 PlatformUsbDeviceHandle handle;
234 const int rv = libusb_open(platform_device_, &handle); 233 const int rv = libusb_open(platform_device_, &handle);
235 if (LIBUSB_SUCCESS == rv) { 234 if (LIBUSB_SUCCESS == rv) {
236 GetConfiguration();
237 if (!current_configuration_cached_) {
238 libusb_close(handle);
239 return NULL;
240 }
241 scoped_refptr<UsbDeviceHandleImpl> device_handle = 235 scoped_refptr<UsbDeviceHandleImpl> device_handle =
242 new UsbDeviceHandleImpl(context_, this, handle, current_configuration_); 236 new UsbDeviceHandleImpl(context_, this, handle);
243 handles_.push_back(device_handle); 237 handles_.push_back(device_handle);
244 return device_handle; 238 return device_handle;
245 } else { 239 } else {
246 VLOG(1) << "Failed to open device: " << ConvertPlatformUsbErrorToString(rv); 240 VLOG(1) << "Failed to open device: " << ConvertPlatformUsbErrorToString(rv);
247 return NULL; 241 return NULL;
248 } 242 }
249 } 243 }
250 244
251 bool UsbDeviceImpl::Close(scoped_refptr<UsbDeviceHandle> handle) { 245 bool UsbDeviceImpl::Close(scoped_refptr<UsbDeviceHandle> handle) {
252 DCHECK(thread_checker_.CalledOnValidThread()); 246 DCHECK(thread_checker_.CalledOnValidThread());
253 247
254 for (HandlesVector::iterator it = handles_.begin(); it != handles_.end(); 248 for (HandlesVector::iterator it = handles_.begin(); it != handles_.end();
255 ++it) { 249 ++it) {
256 if (it->get() == handle.get()) { 250 if (it->get() == handle.get()) {
257 (*it)->InternalClose(); 251 (*it)->InternalClose();
258 handles_.erase(it); 252 handles_.erase(it);
259 return true; 253 return true;
260 } 254 }
261 } 255 }
262 return false; 256 return false;
263 } 257 }
264 258
265 const UsbConfigDescriptor& UsbDeviceImpl::GetConfiguration() { 259 const UsbConfigDescriptor* UsbDeviceImpl::GetConfiguration() {
266 DCHECK(thread_checker_.CalledOnValidThread()); 260 DCHECK(thread_checker_.CalledOnValidThread());
267 261 return configuration_.get();
268 if (!current_configuration_cached_) {
269 libusb_config_descriptor* platform_config;
270 const int rv =
271 libusb_get_active_config_descriptor(platform_device_, &platform_config);
272 if (rv != LIBUSB_SUCCESS) {
273 VLOG(1) << "Failed to get config descriptor: "
274 << ConvertPlatformUsbErrorToString(rv);
275 return current_configuration_;
276 }
277
278 current_configuration_.configuration_value =
279 platform_config->bConfigurationValue;
280 current_configuration_.self_powered =
281 (platform_config->bmAttributes & 0x40) != 0;
282 current_configuration_.remote_wakeup =
283 (platform_config->bmAttributes & 0x20) != 0;
284 current_configuration_.maximum_power = platform_config->MaxPower * 2;
285
286 for (size_t i = 0; i < platform_config->bNumInterfaces; ++i) {
287 const struct libusb_interface* platform_interface =
288 &platform_config->interface[i];
289 for (int j = 0; j < platform_interface->num_altsetting; ++j) {
290 const struct libusb_interface_descriptor* platform_alt_setting =
291 &platform_interface->altsetting[j];
292 UsbInterfaceDescriptor interface;
293
294 interface.interface_number = platform_alt_setting->bInterfaceNumber;
295 interface.alternate_setting = platform_alt_setting->bAlternateSetting;
296 interface.interface_class = platform_alt_setting->bInterfaceClass;
297 interface.interface_subclass = platform_alt_setting->bInterfaceSubClass;
298 interface.interface_protocol = platform_alt_setting->bInterfaceProtocol;
299
300 for (size_t k = 0; k < platform_alt_setting->bNumEndpoints; ++k) {
301 const struct libusb_endpoint_descriptor* platform_endpoint =
302 &platform_alt_setting->endpoint[k];
303 UsbEndpointDescriptor endpoint;
304
305 endpoint.address = platform_endpoint->bEndpointAddress;
306 endpoint.direction = GetDirection(platform_endpoint);
307 endpoint.maximum_packet_size = platform_endpoint->wMaxPacketSize;
308 endpoint.synchronization_type =
309 GetSynchronizationType(platform_endpoint);
310 endpoint.transfer_type = GetTransferType(platform_endpoint);
311 endpoint.usage_type = GetUsageType(platform_endpoint);
312 endpoint.polling_interval = platform_endpoint->bInterval;
313 endpoint.extra_data = std::vector<uint8_t>(
314 platform_endpoint->extra,
315 platform_endpoint->extra + platform_endpoint->extra_length);
316
317 interface.endpoints.push_back(endpoint);
318 }
319
320 interface.extra_data = std::vector<uint8_t>(
321 platform_alt_setting->extra,
322 platform_alt_setting->extra + platform_alt_setting->extra_length);
323
324 current_configuration_.interfaces.push_back(interface);
325 }
326 }
327
328 current_configuration_.extra_data = std::vector<uint8_t>(
329 platform_config->extra,
330 platform_config->extra + platform_config->extra_length);
331
332 libusb_free_config_descriptor(platform_config);
333 current_configuration_cached_ = true;
334 }
335
336 return current_configuration_;
337 } 262 }
338 263
339 bool UsbDeviceImpl::GetManufacturer(base::string16* manufacturer) { 264 bool UsbDeviceImpl::GetManufacturer(base::string16* manufacturer) {
340 DCHECK(thread_checker_.CalledOnValidThread()); 265 DCHECK(thread_checker_.CalledOnValidThread());
341 266
342 #if !defined(USE_UDEV) 267 #if !defined(USE_UDEV)
343 if (!strings_cached_) { 268 if (!strings_cached_) {
344 CacheStrings(); 269 CacheStrings();
345 } 270 }
346 #endif 271 #endif
(...skipping 29 matching lines...) Expand all
376 } 301 }
377 302
378 void UsbDeviceImpl::OnDisconnect() { 303 void UsbDeviceImpl::OnDisconnect() {
379 DCHECK(thread_checker_.CalledOnValidThread()); 304 DCHECK(thread_checker_.CalledOnValidThread());
380 HandlesVector handles; 305 HandlesVector handles;
381 swap(handles, handles_); 306 swap(handles, handles_);
382 for (HandlesVector::iterator it = handles.begin(); it != handles.end(); ++it) 307 for (HandlesVector::iterator it = handles.begin(); it != handles.end(); ++it)
383 (*it)->InternalClose(); 308 (*it)->InternalClose();
384 } 309 }
385 310
311 void UsbDeviceImpl::RefreshConfiguration() {
312 libusb_config_descriptor* platform_config;
313 int rv =
314 libusb_get_active_config_descriptor(platform_device_, &platform_config);
315 if (rv != LIBUSB_SUCCESS) {
316 VLOG(1) << "Failed to get config descriptor: "
317 << ConvertPlatformUsbErrorToString(rv);
318 return;
319 }
320
321 configuration_.reset(new UsbConfigDescriptor());
322 configuration_->configuration_value = platform_config->bConfigurationValue;
323 configuration_->self_powered = (platform_config->bmAttributes & 0x40) != 0;
324 configuration_->remote_wakeup = (platform_config->bmAttributes & 0x20) != 0;
325 configuration_->maximum_power = platform_config->MaxPower * 2;
326
327 for (size_t i = 0; i < platform_config->bNumInterfaces; ++i) {
328 const struct libusb_interface* platform_interface =
329 &platform_config->interface[i];
330 for (int j = 0; j < platform_interface->num_altsetting; ++j) {
331 const struct libusb_interface_descriptor* platform_alt_setting =
332 &platform_interface->altsetting[j];
333 UsbInterfaceDescriptor interface;
334
335 interface.interface_number = platform_alt_setting->bInterfaceNumber;
336 interface.alternate_setting = platform_alt_setting->bAlternateSetting;
337 interface.interface_class = platform_alt_setting->bInterfaceClass;
338 interface.interface_subclass = platform_alt_setting->bInterfaceSubClass;
339 interface.interface_protocol = platform_alt_setting->bInterfaceProtocol;
340
341 for (size_t k = 0; k < platform_alt_setting->bNumEndpoints; ++k) {
342 const struct libusb_endpoint_descriptor* platform_endpoint =
343 &platform_alt_setting->endpoint[k];
344 UsbEndpointDescriptor endpoint;
345
346 endpoint.address = platform_endpoint->bEndpointAddress;
347 endpoint.direction = GetDirection(platform_endpoint);
348 endpoint.maximum_packet_size = platform_endpoint->wMaxPacketSize;
349 endpoint.synchronization_type =
350 GetSynchronizationType(platform_endpoint);
351 endpoint.transfer_type = GetTransferType(platform_endpoint);
352 endpoint.usage_type = GetUsageType(platform_endpoint);
353 endpoint.polling_interval = platform_endpoint->bInterval;
354 endpoint.extra_data = std::vector<uint8_t>(
355 platform_endpoint->extra,
356 platform_endpoint->extra + platform_endpoint->extra_length);
357
358 interface.endpoints.push_back(endpoint);
359 }
360
361 interface.extra_data = std::vector<uint8_t>(
362 platform_alt_setting->extra,
363 platform_alt_setting->extra + platform_alt_setting->extra_length);
364
365 configuration_->interfaces.push_back(interface);
366 }
367 }
368
369 configuration_->extra_data = std::vector<uint8_t>(
370 platform_config->extra,
371 platform_config->extra + platform_config->extra_length);
372
373 libusb_free_config_descriptor(platform_config);
374 }
375
386 #if !defined(USE_UDEV) 376 #if !defined(USE_UDEV)
387 void UsbDeviceImpl::CacheStrings() { 377 void UsbDeviceImpl::CacheStrings() {
388 DCHECK(thread_checker_.CalledOnValidThread()); 378 DCHECK(thread_checker_.CalledOnValidThread());
389 // This is a non-blocking call as libusb has the descriptor in memory. 379 // This is a non-blocking call as libusb has the descriptor in memory.
390 libusb_device_descriptor desc; 380 libusb_device_descriptor desc;
391 const int rv = libusb_get_device_descriptor(platform_device_, &desc); 381 const int rv = libusb_get_device_descriptor(platform_device_, &desc);
392 if (rv == LIBUSB_SUCCESS) { 382 if (rv == LIBUSB_SUCCESS) {
393 scoped_refptr<UsbDeviceHandle> device_handle = Open(); 383 scoped_refptr<UsbDeviceHandle> device_handle = Open();
394 if (device_handle.get()) { 384 if (device_handle.get()) {
395 if (desc.iManufacturer != 0) { 385 if (desc.iManufacturer != 0) {
(...skipping 11 matching lines...) Expand all
407 } 397 }
408 } else { 398 } else {
409 VLOG(1) << "Failed to read device descriptor to cache string descriptors: " 399 VLOG(1) << "Failed to read device descriptor to cache string descriptors: "
410 << ConvertPlatformUsbErrorToString(rv); 400 << ConvertPlatformUsbErrorToString(rv);
411 } 401 }
412 strings_cached_ = true; 402 strings_cached_ = true;
413 } 403 }
414 #endif // !defined(USE_UDEV) 404 #endif // !defined(USE_UDEV)
415 405
416 } // namespace device 406 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698