OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |