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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |