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

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: Rebased. 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
« no previous file with comments | « device/usb/usb_device_impl.h ('k') | extensions/browser/api/usb/usb_api.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 106
107 UsbDeviceImpl::UsbDeviceImpl( 107 UsbDeviceImpl::UsbDeviceImpl(
108 scoped_refptr<UsbContext> context, 108 scoped_refptr<UsbContext> context,
109 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 109 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
110 PlatformUsbDevice platform_device, 110 PlatformUsbDevice platform_device,
111 uint16 vendor_id, 111 uint16 vendor_id,
112 uint16 product_id, 112 uint16 product_id,
113 uint32 unique_id) 113 uint32 unique_id)
114 : UsbDevice(vendor_id, product_id, unique_id), 114 : UsbDevice(vendor_id, product_id, unique_id),
115 platform_device_(platform_device), 115 platform_device_(platform_device),
116 current_configuration_cached_(false),
117 context_(context), 116 context_(context),
118 ui_task_runner_(ui_task_runner) { 117 ui_task_runner_(ui_task_runner) {
119 CHECK(platform_device) << "platform_device cannot be NULL"; 118 CHECK(platform_device) << "platform_device cannot be NULL";
120 libusb_ref_device(platform_device); 119 libusb_ref_device(platform_device);
121 120 RefreshConfiguration();
122 #if defined(USE_UDEV) 121 #if defined(USE_UDEV)
123 ScopedUdevPtr udev(udev_new()); 122 ScopedUdevPtr udev(udev_new());
124 ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev.get())); 123 ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev.get()));
125 124
126 udev_enumerate_add_match_subsystem(enumerate.get(), "usb"); 125 udev_enumerate_add_match_subsystem(enumerate.get(), "usb");
127 if (udev_enumerate_scan_devices(enumerate.get()) != 0) { 126 if (udev_enumerate_scan_devices(enumerate.get()) != 0) {
128 return; 127 return;
129 } 128 }
130 std::string bus_number = 129 std::string bus_number =
131 base::IntToString(libusb_get_bus_number(platform_device)); 130 base::IntToString(libusb_get_bus_number(platform_device));
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 } 209 }
211 } 210 }
212 211
213 #endif 212 #endif
214 213
215 scoped_refptr<UsbDeviceHandle> UsbDeviceImpl::Open() { 214 scoped_refptr<UsbDeviceHandle> UsbDeviceImpl::Open() {
216 DCHECK(thread_checker_.CalledOnValidThread()); 215 DCHECK(thread_checker_.CalledOnValidThread());
217 PlatformUsbDeviceHandle handle; 216 PlatformUsbDeviceHandle handle;
218 const int rv = libusb_open(platform_device_, &handle); 217 const int rv = libusb_open(platform_device_, &handle);
219 if (LIBUSB_SUCCESS == rv) { 218 if (LIBUSB_SUCCESS == rv) {
220 GetConfiguration();
221 if (!current_configuration_cached_) {
222 libusb_close(handle);
223 return NULL;
224 }
225 scoped_refptr<UsbDeviceHandleImpl> device_handle = 219 scoped_refptr<UsbDeviceHandleImpl> device_handle =
226 new UsbDeviceHandleImpl(context_, this, handle, current_configuration_); 220 new UsbDeviceHandleImpl(context_, this, handle);
227 handles_.push_back(device_handle); 221 handles_.push_back(device_handle);
228 return device_handle; 222 return device_handle;
229 } else { 223 } else {
230 VLOG(1) << "Failed to open device: " << ConvertPlatformUsbErrorToString(rv); 224 VLOG(1) << "Failed to open device: " << ConvertPlatformUsbErrorToString(rv);
231 return NULL; 225 return NULL;
232 } 226 }
233 } 227 }
234 228
235 bool UsbDeviceImpl::Close(scoped_refptr<UsbDeviceHandle> handle) { 229 bool UsbDeviceImpl::Close(scoped_refptr<UsbDeviceHandle> handle) {
236 DCHECK(thread_checker_.CalledOnValidThread()); 230 DCHECK(thread_checker_.CalledOnValidThread());
237 231
238 for (HandlesVector::iterator it = handles_.begin(); it != handles_.end(); 232 for (HandlesVector::iterator it = handles_.begin(); it != handles_.end();
239 ++it) { 233 ++it) {
240 if (it->get() == handle.get()) { 234 if (it->get() == handle.get()) {
241 (*it)->InternalClose(); 235 (*it)->InternalClose();
242 handles_.erase(it); 236 handles_.erase(it);
243 return true; 237 return true;
244 } 238 }
245 } 239 }
246 return false; 240 return false;
247 } 241 }
248 242
249 const UsbConfigDescriptor& UsbDeviceImpl::GetConfiguration() { 243 const UsbConfigDescriptor* UsbDeviceImpl::GetConfiguration() {
250 DCHECK(thread_checker_.CalledOnValidThread()); 244 DCHECK(thread_checker_.CalledOnValidThread());
251 245 return configuration_.get();
252 if (!current_configuration_cached_) {
253 libusb_config_descriptor* platform_config;
254 const int rv =
255 libusb_get_active_config_descriptor(platform_device_, &platform_config);
256 if (rv != LIBUSB_SUCCESS) {
257 VLOG(1) << "Failed to get config descriptor: "
258 << ConvertPlatformUsbErrorToString(rv);
259 return current_configuration_;
260 }
261
262 current_configuration_.configuration_value =
263 platform_config->bConfigurationValue;
264 current_configuration_.self_powered =
265 (platform_config->bmAttributes & 0x40) != 0;
266 current_configuration_.remote_wakeup =
267 (platform_config->bmAttributes & 0x20) != 0;
268 current_configuration_.maximum_power = platform_config->MaxPower * 2;
269
270 for (size_t i = 0; i < platform_config->bNumInterfaces; ++i) {
271 const struct libusb_interface* platform_interface =
272 &platform_config->interface[i];
273 for (int j = 0; j < platform_interface->num_altsetting; ++j) {
274 const struct libusb_interface_descriptor* platform_alt_setting =
275 &platform_interface->altsetting[j];
276 UsbInterfaceDescriptor interface;
277
278 interface.interface_number = platform_alt_setting->bInterfaceNumber;
279 interface.alternate_setting = platform_alt_setting->bAlternateSetting;
280 interface.interface_class = platform_alt_setting->bInterfaceClass;
281 interface.interface_subclass = platform_alt_setting->bInterfaceSubClass;
282 interface.interface_protocol = platform_alt_setting->bInterfaceProtocol;
283
284 for (size_t k = 0; k < platform_alt_setting->bNumEndpoints; ++k) {
285 const struct libusb_endpoint_descriptor* platform_endpoint =
286 &platform_alt_setting->endpoint[k];
287 UsbEndpointDescriptor endpoint;
288
289 endpoint.address = platform_endpoint->bEndpointAddress;
290 endpoint.direction = GetDirection(platform_endpoint);
291 endpoint.maximum_packet_size = platform_endpoint->wMaxPacketSize;
292 endpoint.synchronization_type =
293 GetSynchronizationType(platform_endpoint);
294 endpoint.transfer_type = GetTransferType(platform_endpoint);
295 endpoint.usage_type = GetUsageType(platform_endpoint);
296 endpoint.polling_interval = platform_endpoint->bInterval;
297 endpoint.extra_data = std::vector<uint8_t>(
298 platform_endpoint->extra,
299 platform_endpoint->extra + platform_endpoint->extra_length);
300
301 interface.endpoints.push_back(endpoint);
302 }
303
304 interface.extra_data = std::vector<uint8_t>(
305 platform_alt_setting->extra,
306 platform_alt_setting->extra + platform_alt_setting->extra_length);
307
308 current_configuration_.interfaces.push_back(interface);
309 }
310 }
311
312 current_configuration_.extra_data = std::vector<uint8_t>(
313 platform_config->extra,
314 platform_config->extra + platform_config->extra_length);
315
316 libusb_free_config_descriptor(platform_config);
317 current_configuration_cached_ = true;
318 }
319
320 return current_configuration_;
321 } 246 }
322 247
323 bool UsbDeviceImpl::GetManufacturer(base::string16* manufacturer) { 248 bool UsbDeviceImpl::GetManufacturer(base::string16* manufacturer) {
324 DCHECK(thread_checker_.CalledOnValidThread()); 249 DCHECK(thread_checker_.CalledOnValidThread());
325 250
326 #if !defined(USE_UDEV) 251 #if !defined(USE_UDEV)
327 if (!strings_cached_) { 252 if (!strings_cached_) {
328 CacheStrings(); 253 CacheStrings();
329 } 254 }
330 #endif 255 #endif
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 // Swap the list of handles into a local variable because closing all open 290 // Swap the list of handles into a local variable because closing all open
366 // handles may release the last reference to this object. 291 // handles may release the last reference to this object.
367 HandlesVector handles; 292 HandlesVector handles;
368 swap(handles, handles_); 293 swap(handles, handles_);
369 294
370 for (const scoped_refptr<UsbDeviceHandleImpl>& handle : handles_) { 295 for (const scoped_refptr<UsbDeviceHandleImpl>& handle : handles_) {
371 handle->InternalClose(); 296 handle->InternalClose();
372 } 297 }
373 } 298 }
374 299
300 void UsbDeviceImpl::RefreshConfiguration() {
301 libusb_config_descriptor* platform_config;
302 int rv =
303 libusb_get_active_config_descriptor(platform_device_, &platform_config);
304 if (rv != LIBUSB_SUCCESS) {
305 VLOG(1) << "Failed to get config descriptor: "
306 << ConvertPlatformUsbErrorToString(rv);
307 return;
308 }
309
310 configuration_.reset(new UsbConfigDescriptor());
311 configuration_->configuration_value = platform_config->bConfigurationValue;
312 configuration_->self_powered = (platform_config->bmAttributes & 0x40) != 0;
313 configuration_->remote_wakeup = (platform_config->bmAttributes & 0x20) != 0;
314 configuration_->maximum_power = platform_config->MaxPower * 2;
315
316 for (size_t i = 0; i < platform_config->bNumInterfaces; ++i) {
317 const struct libusb_interface* platform_interface =
318 &platform_config->interface[i];
319 for (int j = 0; j < platform_interface->num_altsetting; ++j) {
320 const struct libusb_interface_descriptor* platform_alt_setting =
321 &platform_interface->altsetting[j];
322 UsbInterfaceDescriptor interface;
323
324 interface.interface_number = platform_alt_setting->bInterfaceNumber;
325 interface.alternate_setting = platform_alt_setting->bAlternateSetting;
326 interface.interface_class = platform_alt_setting->bInterfaceClass;
327 interface.interface_subclass = platform_alt_setting->bInterfaceSubClass;
328 interface.interface_protocol = platform_alt_setting->bInterfaceProtocol;
329
330 for (size_t k = 0; k < platform_alt_setting->bNumEndpoints; ++k) {
331 const struct libusb_endpoint_descriptor* platform_endpoint =
332 &platform_alt_setting->endpoint[k];
333 UsbEndpointDescriptor endpoint;
334
335 endpoint.address = platform_endpoint->bEndpointAddress;
336 endpoint.direction = GetDirection(platform_endpoint);
337 endpoint.maximum_packet_size = platform_endpoint->wMaxPacketSize;
338 endpoint.synchronization_type =
339 GetSynchronizationType(platform_endpoint);
340 endpoint.transfer_type = GetTransferType(platform_endpoint);
341 endpoint.usage_type = GetUsageType(platform_endpoint);
342 endpoint.polling_interval = platform_endpoint->bInterval;
343 endpoint.extra_data = std::vector<uint8_t>(
344 platform_endpoint->extra,
345 platform_endpoint->extra + platform_endpoint->extra_length);
346
347 interface.endpoints.push_back(endpoint);
348 }
349
350 interface.extra_data = std::vector<uint8_t>(
351 platform_alt_setting->extra,
352 platform_alt_setting->extra + platform_alt_setting->extra_length);
353
354 configuration_->interfaces.push_back(interface);
355 }
356 }
357
358 configuration_->extra_data = std::vector<uint8_t>(
359 platform_config->extra,
360 platform_config->extra + platform_config->extra_length);
361
362 libusb_free_config_descriptor(platform_config);
363 }
364
375 #if !defined(USE_UDEV) 365 #if !defined(USE_UDEV)
376 void UsbDeviceImpl::CacheStrings() { 366 void UsbDeviceImpl::CacheStrings() {
377 DCHECK(thread_checker_.CalledOnValidThread()); 367 DCHECK(thread_checker_.CalledOnValidThread());
378 // This is a non-blocking call as libusb has the descriptor in memory. 368 // This is a non-blocking call as libusb has the descriptor in memory.
379 libusb_device_descriptor desc; 369 libusb_device_descriptor desc;
380 const int rv = libusb_get_device_descriptor(platform_device_, &desc); 370 const int rv = libusb_get_device_descriptor(platform_device_, &desc);
381 if (rv == LIBUSB_SUCCESS) { 371 if (rv == LIBUSB_SUCCESS) {
382 scoped_refptr<UsbDeviceHandle> device_handle = Open(); 372 scoped_refptr<UsbDeviceHandle> device_handle = Open();
383 if (device_handle.get()) { 373 if (device_handle.get()) {
384 if (desc.iManufacturer != 0) { 374 if (desc.iManufacturer != 0) {
(...skipping 11 matching lines...) Expand all
396 } 386 }
397 } else { 387 } else {
398 VLOG(1) << "Failed to read device descriptor to cache string descriptors: " 388 VLOG(1) << "Failed to read device descriptor to cache string descriptors: "
399 << ConvertPlatformUsbErrorToString(rv); 389 << ConvertPlatformUsbErrorToString(rv);
400 } 390 }
401 strings_cached_ = true; 391 strings_cached_ = true;
402 } 392 }
403 #endif // !defined(USE_UDEV) 393 #endif // !defined(USE_UDEV)
404 394
405 } // namespace device 395 } // namespace device
OLDNEW
« no previous file with comments | « device/usb/usb_device_impl.h ('k') | extensions/browser/api/usb/usb_api.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698