1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/extensions/api/usb/usb_api.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "base/memory/scoped_ptr.h" 11 #include "base/message_loop/message_loop_proxy.h" 12 #include "chrome/browser/extensions/api/usb/usb_device_resource.h" 13 #include "chrome/browser/extensions/extension_system.h" 14 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/usb/usb_device_handle.h" 16 #include "chrome/browser/usb/usb_service.h" 17 #include "chrome/common/extensions/api/usb.h" 18 #include "chrome/common/extensions/permissions/usb_device_permission.h" 19 #include "extensions/common/permissions/permissions_data.h" 20 21 namespace usb = extensions::api::usb; 22 namespace BulkTransfer = usb::BulkTransfer; 23 namespace ClaimInterface = usb::ClaimInterface; 24 namespace CloseDevice = usb::CloseDevice; 25 namespace ControlTransfer = usb::ControlTransfer; 26 namespace FindDevices = usb::FindDevices; 27 namespace GetDevices = usb::GetDevices; 28 namespace InterruptTransfer = usb::InterruptTransfer; 29 namespace IsochronousTransfer = usb::IsochronousTransfer; 30 namespace ListInterfaces = usb::ListInterfaces; 31 namespace OpenDevice = usb::OpenDevice; 32 namespace ReleaseInterface = usb::ReleaseInterface; 33 namespace RequestAccess = usb::RequestAccess; 34 namespace ResetDevice = usb::ResetDevice; 35 namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting; 36 37 using content::BrowserThread; 38 using std::string; 39 using std::vector; 40 using usb::ControlTransferInfo; 41 using usb::ConnectionHandle; 42 using usb::Device; 43 using usb::Direction; 44 using usb::EndpointDescriptor; 45 using usb::GenericTransferInfo; 46 using usb::InterfaceDescriptor; 47 using usb::IsochronousTransferInfo; 48 using usb::Recipient; 49 using usb::RequestType; 50 using usb::SynchronizationType; 51 using usb::TransferType; 52 using usb::UsageType; 53 54 typedef std::vector<scoped_refptr<UsbDevice> > DeviceVector; 55 typedef scoped_ptr<DeviceVector> ScopedDeviceVector; 56 57 namespace { 58 59 const char kDataKey[] = "data"; 60 const char kResultCodeKey[] = "resultCode"; 61 62 const char kErrorInitService[] = "Failed to initialize USB service."; 63 64 const char kErrorOpen[] = "Failed to open device."; 65 const char kErrorCancelled[] = "Transfer was cancelled."; 66 const char kErrorDisconnect[] = "Device disconnected."; 67 const char kErrorGeneric[] = "Transfer failed."; 68 #if !defined(OS_CHROMEOS) 69 const char kErrorNotSupported[] = "Not supported on this platform."; 70 #endif 71 const char kErrorOverflow[] = "Inbound transfer overflow."; 72 const char kErrorStalled[] = "Transfer stalled."; 73 const char kErrorTimeout[] = "Transfer timed out."; 74 const char kErrorTransferLength[] = "Transfer length is insufficient."; 75 76 const char kErrorCannotListInterfaces[] = "Error listing interfaces."; 77 const char kErrorCannotClaimInterface[] = "Error claiming interface."; 78 const char kErrorCannotReleaseInterface[] = "Error releasing interface."; 79 const char kErrorCannotSetInterfaceAlternateSetting[] = 80 "Error setting alternate interface setting."; 81 const char kErrorConvertDirection[] = "Invalid transfer direction."; 82 const char kErrorConvertRecipient[] = "Invalid transfer recipient."; 83 const char kErrorConvertRequestType[] = "Invalid request type."; 84 const char kErrorConvertSynchronizationType[] = "Invalid synchronization type"; 85 const char kErrorConvertTransferType[] = "Invalid endpoint type."; 86 const char kErrorConvertUsageType[] = "Invalid usage type."; 87 const char kErrorMalformedParameters[] = "Error parsing parameters."; 88 const char kErrorNoDevice[] = "No such device."; 89 const char kErrorPermissionDenied[] = 90 "Permission to access device was denied"; 91 const char kErrorInvalidTransferLength[] = 92 "Transfer length must be a positive number less than 104,857,600."; 93 const char kErrorInvalidNumberOfPackets[] = 94 "Number of packets must be a positive number less than 4,194,304."; 95 const char kErrorInvalidPacketLength[] = "Packet length must be a " 96 "positive number less than 65,536."; 97 const char kErrorResetDevice[] = 98 "Error resetting the device. The device has been closed."; 99 100 const size_t kMaxTransferLength = 100 * 1024 * 1024; 101 const int kMaxPackets = 4 * 1024 * 1024; 102 const int kMaxPacketLength = 64 * 1024; 103 104 UsbDevice* g_device_for_test = NULL; 105 106 bool ConvertDirectionToApi(const UsbEndpointDirection& input, 107 Direction* output) { 108 switch (input) { 109 case USB_DIRECTION_INBOUND: 110 *output = usb::DIRECTION_IN; 111 return true; 112 case USB_DIRECTION_OUTBOUND: 113 *output = usb::DIRECTION_OUT; 114 return true; 115 default: 116 NOTREACHED(); 117 return false; 118 } 119 } 120 121 bool ConvertSynchronizationTypeToApi(const UsbSynchronizationType& input, 122 usb::SynchronizationType* output) { 123 switch (input) { 124 case USB_SYNCHRONIZATION_NONE: 125 *output = usb::SYNCHRONIZATION_TYPE_NONE; 126 return true; 127 case USB_SYNCHRONIZATION_ASYNCHRONOUS: 128 *output = usb::SYNCHRONIZATION_TYPE_ASYNCHRONOUS; 129 return true; 130 case USB_SYNCHRONIZATION_ADAPTIVE: 131 *output = usb::SYNCHRONIZATION_TYPE_ADAPTIVE; 132 return true; 133 case USB_SYNCHRONIZATION_SYNCHRONOUS: 134 *output = usb::SYNCHRONIZATION_TYPE_SYNCHRONOUS; 135 return true; 136 default: 137 NOTREACHED(); 138 return false; 139 } 140 } 141 142 bool ConvertTransferTypeToApi( 143 const UsbTransferType& input, 144 usb::TransferType* output) { 145 switch (input) { 146 case USB_TRANSFER_CONTROL: 147 *output = usb::TRANSFER_TYPE_CONTROL; 148 return true; 149 case USB_TRANSFER_INTERRUPT: 150 *output = usb::TRANSFER_TYPE_INTERRUPT; 151 return true; 152 case USB_TRANSFER_ISOCHRONOUS: 153 *output = usb::TRANSFER_TYPE_ISOCHRONOUS; 154 return true; 155 case USB_TRANSFER_BULK: 156 *output = usb::TRANSFER_TYPE_BULK; 157 return true; 158 default: 159 NOTREACHED(); 160 return false; 161 } 162 } 163 164 bool ConvertUsageTypeToApi(const UsbUsageType& input, usb::UsageType* output) { 165 switch (input) { 166 case USB_USAGE_DATA: 167 *output = usb::USAGE_TYPE_DATA; 168 return true; 169 case USB_USAGE_FEEDBACK: 170 *output = usb::USAGE_TYPE_FEEDBACK; 171 return true; 172 case USB_USAGE_EXPLICIT_FEEDBACK: 173 *output = usb::USAGE_TYPE_EXPLICITFEEDBACK; 174 return true; 175 default: 176 NOTREACHED(); 177 return false; 178 } 179 } 180 181 bool ConvertDirection(const Direction& input, 182 UsbEndpointDirection* output) { 183 switch (input) { 184 case usb::DIRECTION_IN: 185 *output = USB_DIRECTION_INBOUND; 186 return true; 187 case usb::DIRECTION_OUT: 188 *output = USB_DIRECTION_OUTBOUND; 189 return true; 190 default: 191 NOTREACHED(); 192 return false; 193 } 194 } 195 196 bool ConvertRequestType(const RequestType& input, 197 UsbDeviceHandle::TransferRequestType* output) { 198 switch (input) { 199 case usb::REQUEST_TYPE_STANDARD: 200 *output = UsbDeviceHandle::STANDARD; 201 return true; 202 case usb::REQUEST_TYPE_CLASS: 203 *output = UsbDeviceHandle::CLASS; 204 return true; 205 case usb::REQUEST_TYPE_VENDOR: 206 *output = UsbDeviceHandle::VENDOR; 207 return true; 208 case usb::REQUEST_TYPE_RESERVED: 209 *output = UsbDeviceHandle::RESERVED; 210 return true; 211 default: 212 NOTREACHED(); 213 return false; 214 } 215 } 216 217 bool ConvertRecipient(const Recipient& input, 218 UsbDeviceHandle::TransferRecipient* output) { 219 switch (input) { 220 case usb::RECIPIENT_DEVICE: 221 *output = UsbDeviceHandle::DEVICE; 222 return true; 223 case usb::RECIPIENT_INTERFACE: 224 *output = UsbDeviceHandle::INTERFACE; 225 return true; 226 case usb::RECIPIENT_ENDPOINT: 227 *output = UsbDeviceHandle::ENDPOINT; 228 return true; 229 case usb::RECIPIENT_OTHER: 230 *output = UsbDeviceHandle::OTHER; 231 return true; 232 default: 233 NOTREACHED(); 234 return false; 235 } 236 } 237 238 template<class T> 239 bool GetTransferSize(const T& input, size_t* output) { 240 if (input.direction == usb::DIRECTION_IN) { 241 const int* length = input.length.get(); 242 if (length && *length >= 0 && 243 static_cast<size_t>(*length) < kMaxTransferLength) { 244 *output = *length; 245 return true; 246 } 247 } else if (input.direction == usb::DIRECTION_OUT) { 248 if (input.data.get()) { 249 *output = input.data->size(); 250 return true; 251 } 252 } 253 return false; 254 } 255 256 template<class T> 257 scoped_refptr<net::IOBuffer> CreateBufferForTransfer( 258 const T& input, UsbEndpointDirection direction, size_t size) { 259 260 if (size >= kMaxTransferLength) 261 return NULL; 262 263 // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This 264 // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer 265 // cannot represent a zero-length buffer, while an URB can. 266 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(std::max( 267 static_cast<size_t>(1), size)); 268 269 if (direction == USB_DIRECTION_INBOUND) { 270 return buffer; 271 } else if (direction == USB_DIRECTION_OUTBOUND) { 272 if (input.data.get() && size <= input.data->size()) { 273 memcpy(buffer->data(), input.data->data(), size); 274 return buffer; 275 } 276 } 277 NOTREACHED(); 278 return NULL; 279 } 280 281 const char* ConvertTransferStatusToErrorString(const UsbTransferStatus status) { 282 switch (status) { 283 case USB_TRANSFER_COMPLETED: 284 return ""; 285 case USB_TRANSFER_ERROR: 286 return kErrorGeneric; 287 case USB_TRANSFER_TIMEOUT: 288 return kErrorTimeout; 289 case USB_TRANSFER_CANCELLED: 290 return kErrorCancelled; 291 case USB_TRANSFER_STALLED: 292 return kErrorStalled; 293 case USB_TRANSFER_DISCONNECT: 294 return kErrorDisconnect; 295 case USB_TRANSFER_OVERFLOW: 296 return kErrorOverflow; 297 case USB_TRANSFER_LENGTH_SHORT: 298 return kErrorTransferLength; 299 default: 300 NOTREACHED(); 301 return ""; 302 } 303 } 304 305 #if defined(OS_CHROMEOS) 306 void RequestUsbDevicesAccessHelper( 307 ScopedDeviceVector devices, 308 std::vector<scoped_refptr<UsbDevice> >::iterator i, 309 int interface_id, 310 const base::Callback<void(ScopedDeviceVector result)>& callback, 311 bool success) { 312 if (success) { 313 ++i; 314 } else { 315 i = devices->erase(i); 316 } 317 if (i == devices->end()) { 318 callback.Run(devices.Pass()); 319 return; 320 } 321 (*i)->RequestUsbAcess(interface_id, base::Bind(RequestUsbDevicesAccessHelper, 322 base::Passed(devices.Pass()), 323 i, interface_id, callback)); 324 } 325 326 void RequestUsbDevicesAccess( 327 ScopedDeviceVector devices, 328 int interface_id, 329 const base::Callback<void(ScopedDeviceVector result)>& callback) { 330 if (devices->empty()) { 331 callback.Run(devices.Pass()); 332 return; 333 } 334 std::vector<scoped_refptr<UsbDevice> >::iterator i = devices->begin(); 335 (*i)->RequestUsbAcess( 336 interface_id, 337 base::Bind(RequestUsbDevicesAccessHelper, base::Passed(devices.Pass()), 338 i, interface_id, callback)); 339 } 340 #endif // OS_CHROMEOS 341 342 base::DictionaryValue* CreateTransferInfo( 343 UsbTransferStatus status, 344 scoped_refptr<net::IOBuffer> data, 345 size_t length) { 346 base::DictionaryValue* result = new base::DictionaryValue(); 347 result->SetInteger(kResultCodeKey, status); 348 result->Set(kDataKey, base::BinaryValue::CreateWithCopiedBuffer(data->data(), 349 length)); 350 return result; 351 } 352 353 base::Value* PopulateConnectionHandle(int handle, int vendor_id, 354 int product_id) { 355 ConnectionHandle result; 356 result.handle = handle; 357 result.vendor_id = vendor_id; 358 result.product_id = product_id; 359 return result.ToValue().release(); 360 } 361 362 base::Value* PopulateDevice(UsbDevice* device) { 363 Device result; 364 result.device = device->unique_id(); 365 result.vendor_id = device->vendor_id(); 366 result.product_id = device->product_id(); 367 return result.ToValue().release(); 368 } 369 370 base::Value* PopulateInterfaceDescriptor( 371 int interface_number, 372 int alternate_setting, 373 int interface_class, 374 int interface_subclass, 375 int interface_protocol, 376 std::vector<linked_ptr<EndpointDescriptor> >* endpoints) { 377 InterfaceDescriptor descriptor; 378 descriptor.interface_number = interface_number; 379 descriptor.alternate_setting = alternate_setting; 380 descriptor.interface_class = interface_class; 381 descriptor.interface_subclass = interface_subclass; 382 descriptor.interface_protocol = interface_protocol; 383 descriptor.endpoints = *endpoints; 384 return descriptor.ToValue().release(); 385 } 386 387 } // namespace 388 389 namespace extensions { 390 391 UsbAsyncApiFunction::UsbAsyncApiFunction() 392 : manager_(NULL) { 393 } 394 395 UsbAsyncApiFunction::~UsbAsyncApiFunction() { 396 } 397 398 bool UsbAsyncApiFunction::PrePrepare() { 399 manager_ = ApiResourceManager<UsbDeviceResource>::Get(GetProfile()); 400 set_work_thread_id(BrowserThread::FILE); 401 return manager_ != NULL; 402 } 403 404 bool UsbAsyncApiFunction::Respond() { 405 return error_.empty(); 406 } 407 408 scoped_refptr<UsbDevice> 409 UsbAsyncApiFunction::GetDeviceOrOrCompleteWithError( 410 const Device& input_device) { 411 if (g_device_for_test) 412 return g_device_for_test; 413 414 const uint16_t vendor_id = input_device.vendor_id; 415 const uint16_t product_id = input_device.product_id; 416 UsbDevicePermission::CheckParam param( 417 vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE); 418 if (!PermissionsData::CheckAPIPermissionWithParam( 419 GetExtension(), APIPermission::kUsbDevice, ¶m)) { 420 LOG(WARNING) << "Insufficient permissions to access device."; 421 CompleteWithError(kErrorPermissionDenied); 422 return NULL; 423 } 424 425 UsbService* service = UsbService::GetInstance(); 426 if (!service) { 427 CompleteWithError(kErrorInitService); 428 return NULL; 429 } 430 scoped_refptr<UsbDevice> device; 431 432 device = service->GetDeviceById(input_device.device); 433 434 if (!device) { 435 CompleteWithError(kErrorNoDevice); 436 return NULL; 437 } 438 439 if (device->vendor_id() != input_device.vendor_id || 440 device->product_id() != input_device.product_id) { 441 // Must act as if there is no such a device. 442 // Otherwise can be used to finger print unauthorized devices. 443 CompleteWithError(kErrorNoDevice); 444 return NULL; 445 } 446 447 return device; 448 } 449 450 scoped_refptr<UsbDeviceHandle> 451 UsbAsyncApiFunction::GetDeviceHandleOrCompleteWithError( 452 const ConnectionHandle& input_device_handle) { 453 UsbDeviceResource* resource = 454 manager_->Get(extension_->id(), input_device_handle.handle); 455 if (!resource) { 456 CompleteWithError(kErrorNoDevice); 457 return NULL; 458 } 459 460 if (!resource->device() || !resource->device()->device()) { 461 CompleteWithError(kErrorDisconnect); 462 manager_->Remove(extension_->id(), input_device_handle.handle); 463 return NULL; 464 } 465 466 if (resource->device()->device()->vendor_id() != 467 input_device_handle.vendor_id || 468 resource->device()->device()->product_id() != 469 input_device_handle.product_id) { 470 CompleteWithError(kErrorNoDevice); 471 return NULL; 472 } 473 474 return resource->device(); 475 } 476 477 void UsbAsyncApiFunction::RemoveUsbDeviceResource(int api_resource_id) { 478 manager_->Remove(extension_->id(), api_resource_id); 479 } 480 481 void UsbAsyncApiFunction::CompleteWithError(const std::string& error) { 482 SetError(error); 483 AsyncWorkCompleted(); 484 } 485 486 UsbAsyncApiTransferFunction::UsbAsyncApiTransferFunction() {} 487 488 UsbAsyncApiTransferFunction::~UsbAsyncApiTransferFunction() {} 489 490 void UsbAsyncApiTransferFunction::OnCompleted(UsbTransferStatus status, 491 scoped_refptr<net::IOBuffer> data, 492 size_t length) { 493 if (status != USB_TRANSFER_COMPLETED) 494 SetError(ConvertTransferStatusToErrorString(status)); 495 496 SetResult(CreateTransferInfo(status, data, length)); 497 AsyncWorkCompleted(); 498 } 499 500 bool UsbAsyncApiTransferFunction::ConvertDirectionSafely( 501 const Direction& input, UsbEndpointDirection* output) { 502 const bool converted = ConvertDirection(input, output); 503 if (!converted) 504 SetError(kErrorConvertDirection); 505 return converted; 506 } 507 508 bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely( 509 const RequestType& input, UsbDeviceHandle::TransferRequestType* output) { 510 const bool converted = ConvertRequestType(input, output); 511 if (!converted) 512 SetError(kErrorConvertRequestType); 513 return converted; 514 } 515 516 bool UsbAsyncApiTransferFunction::ConvertRecipientSafely( 517 const Recipient& input, UsbDeviceHandle::TransferRecipient* output) { 518 const bool converted = ConvertRecipient(input, output); 519 if (!converted) 520 SetError(kErrorConvertRecipient); 521 return converted; 522 } 523 524 UsbFindDevicesFunction::UsbFindDevicesFunction() {} 525 526 UsbFindDevicesFunction::~UsbFindDevicesFunction() {} 527 528 bool UsbFindDevicesFunction::Prepare() { 529 parameters_ = FindDevices::Params::Create(*args_); 530 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 531 return true; 532 } 533 534 void UsbFindDevicesFunction::AsyncWorkStart() { 535 scoped_ptr<base::ListValue> result(new base::ListValue()); 536 537 if (g_device_for_test) { 538 UsbDeviceResource* const resource = new UsbDeviceResource( 539 extension_->id(), 540 g_device_for_test->Open()); 541 542 result->Append(PopulateConnectionHandle(manager_->Add(resource), 0, 0)); 543 SetResult(result.release()); 544 AsyncWorkCompleted(); 545 return; 546 } 547 548 const uint16_t vendor_id = parameters_->options.vendor_id; 549 const uint16_t product_id = parameters_->options.product_id; 550 int interface_id = parameters_->options.interface_id.get() ? 551 *parameters_->options.interface_id.get() : 552 UsbDevicePermissionData::ANY_INTERFACE; 553 UsbDevicePermission::CheckParam param(vendor_id, product_id, interface_id); 554 if (!PermissionsData::CheckAPIPermissionWithParam( 555 GetExtension(), APIPermission::kUsbDevice, ¶m)) { 556 LOG(WARNING) << "Insufficient permissions to access device."; 557 CompleteWithError(kErrorPermissionDenied); 558 return; 559 } 560 561 UsbService *service = UsbService::GetInstance(); 562 if (!service) { 563 CompleteWithError(kErrorInitService); 564 return; 565 } 566 567 ScopedDeviceVector devices(new DeviceVector()); 568 service->GetDevices(devices.get()); 569 570 for (DeviceVector::iterator it = devices->begin(); 571 it != devices->end();) { 572 if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) { 573 it = devices->erase(it); 574 } else { 575 ++it; 576 } 577 } 578 579 #if defined(OS_CHROMEOS) 580 RequestUsbDevicesAccess( 581 devices.Pass(), interface_id, 582 base::Bind(&UsbFindDevicesFunction::OpenDevices, this)); 583 #else 584 OpenDevices(devices.Pass()); 585 #endif // OS_CHROMEOS 586 } 587 588 void UsbFindDevicesFunction::OpenDevices(ScopedDeviceVector devices) { 589 base::ListValue* result = new base::ListValue(); 590 591 for (size_t i = 0; i < devices->size(); ++i) { 592 scoped_refptr<UsbDeviceHandle> device_handle = 593 devices->at(i)->Open(); 594 if (device_handle) 595 device_handles_.push_back(device_handle); 596 } 597 598 for (size_t i = 0; i < device_handles_.size(); ++i) { 599 UsbDeviceHandle* const device_handle = device_handles_[i].get(); 600 UsbDeviceResource* const resource = 601 new UsbDeviceResource(extension_->id(), device_handle); 602 603 result->Append(PopulateConnectionHandle(manager_->Add(resource), 604 parameters_->options.vendor_id, 605 parameters_->options.product_id)); 606 } 607 608 SetResult(result); 609 AsyncWorkCompleted(); 610 } 611 612 UsbGetDevicesFunction::UsbGetDevicesFunction() { 613 } 614 615 UsbGetDevicesFunction::~UsbGetDevicesFunction() { 616 } 617 618 void UsbGetDevicesFunction::SetDeviceForTest(UsbDevice* device) { 619 g_device_for_test = device; 620 } 621 622 bool UsbGetDevicesFunction::Prepare() { 623 parameters_ = GetDevices::Params::Create(*args_); 624 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 625 return true; 626 } 627 628 void UsbGetDevicesFunction::AsyncWorkStart() { 629 scoped_ptr<base::ListValue> result(new base::ListValue()); 630 631 if (g_device_for_test) { 632 result->Append(PopulateDevice(g_device_for_test)); 633 SetResult(result.release()); 634 AsyncWorkCompleted(); 635 return; 636 } 637 638 const uint16_t vendor_id = parameters_->options.vendor_id; 639 const uint16_t product_id = parameters_->options.product_id; 640 UsbDevicePermission::CheckParam param( 641 vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE); 642 if (!PermissionsData::CheckAPIPermissionWithParam( 643 GetExtension(), APIPermission::kUsbDevice, ¶m)) { 644 LOG(WARNING) << "Insufficient permissions to access device."; 645 CompleteWithError(kErrorPermissionDenied); 646 return; 647 } 648 649 UsbService* service = UsbService::GetInstance(); 650 if (!service) { 651 CompleteWithError(kErrorInitService); 652 return; 653 } 654 655 DeviceVector devices; 656 service->GetDevices(&devices); 657 658 for (DeviceVector::iterator it = devices.begin(); it != devices.end();) { 659 if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) { 660 it = devices.erase(it); 661 } else { 662 ++it; 663 } 664 } 665 666 for (size_t i = 0; i < devices.size(); ++i) { 667 result->Append(PopulateDevice(devices[i].get())); 668 } 669 670 SetResult(result.release()); 671 AsyncWorkCompleted(); 672 } 673 674 UsbRequestAccessFunction::UsbRequestAccessFunction() {} 675 676 UsbRequestAccessFunction::~UsbRequestAccessFunction() {} 677 678 bool UsbRequestAccessFunction::Prepare() { 679 parameters_ = RequestAccess::Params::Create(*args_); 680 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 681 return true; 682 } 683 684 void UsbRequestAccessFunction::AsyncWorkStart() { 685 #if defined(OS_CHROMEOS) 686 scoped_refptr<UsbDevice> device = 687 GetDeviceOrOrCompleteWithError(parameters_->device); 688 if (!device) return; 689 690 device->RequestUsbAcess(parameters_->interface_id, 691 base::Bind(&UsbRequestAccessFunction::OnCompleted, 692 this)); 693 #else 694 SetResult(new base::FundamentalValue(false)); 695 CompleteWithError(kErrorNotSupported); 696 #endif // OS_CHROMEOS 697 } 698 699 void UsbRequestAccessFunction::OnCompleted(bool success) { 700 SetResult(new base::FundamentalValue(success)); 701 AsyncWorkCompleted(); 702 } 703 704 UsbOpenDeviceFunction::UsbOpenDeviceFunction() {} 705 706 UsbOpenDeviceFunction::~UsbOpenDeviceFunction() {} 707 708 bool UsbOpenDeviceFunction::Prepare() { 709 parameters_ = OpenDevice::Params::Create(*args_); 710 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 711 return true; 712 } 713 714 void UsbOpenDeviceFunction::AsyncWorkStart() { 715 scoped_refptr<UsbDevice> device = 716 GetDeviceOrOrCompleteWithError(parameters_->device); 717 if (!device) return; 718 719 handle_ = device->Open(); 720 if (!handle_) { 721 SetError(kErrorOpen); 722 AsyncWorkCompleted(); 723 return; 724 } 725 726 SetResult(PopulateConnectionHandle( 727 manager_->Add(new UsbDeviceResource(extension_->id(), handle_)), 728 handle_->device()->vendor_id(), 729 handle_->device()->product_id())); 730 AsyncWorkCompleted(); 731 } 732 733 UsbListInterfacesFunction::UsbListInterfacesFunction() {} 734 735 UsbListInterfacesFunction::~UsbListInterfacesFunction() {} 736 737 bool UsbListInterfacesFunction::Prepare() { 738 parameters_ = ListInterfaces::Params::Create(*args_); 739 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 740 return true; 741 } 742 743 void UsbListInterfacesFunction::AsyncWorkStart() { 744 scoped_refptr<UsbDeviceHandle> device_handle = 745 GetDeviceHandleOrCompleteWithError(parameters_->handle); 746 if (!device_handle) return; 747 748 scoped_refptr<UsbConfigDescriptor> config = 749 device_handle->device()->ListInterfaces(); 750 751 if (!config) { 752 SetError(kErrorCannotListInterfaces); 753 AsyncWorkCompleted(); 754 return; 755 } 756 757 result_.reset(new base::ListValue()); 758 759 for (size_t i = 0, num_interfaces = config->GetNumInterfaces(); 760 i < num_interfaces; ++i) { 761 scoped_refptr<const UsbInterfaceDescriptor> 762 usb_interface(config->GetInterface(i)); 763 for (size_t j = 0, num_descriptors = usb_interface->GetNumAltSettings(); 764 j < num_descriptors; ++j) { 765 scoped_refptr<const UsbInterfaceAltSettingDescriptor> descriptor 766 = usb_interface->GetAltSetting(j); 767 std::vector<linked_ptr<EndpointDescriptor> > endpoints; 768 for (size_t k = 0, num_endpoints = descriptor->GetNumEndpoints(); 769 k < num_endpoints; k++) { 770 scoped_refptr<const UsbEndpointDescriptor> endpoint 771 = descriptor->GetEndpoint(k); 772 linked_ptr<EndpointDescriptor> endpoint_desc(new EndpointDescriptor()); 773 774 TransferType type; 775 Direction direction; 776 SynchronizationType synchronization; 777 UsageType usage; 778 779 if (!ConvertTransferTypeSafely(endpoint->GetTransferType(), &type) || 780 !ConvertDirectionSafely(endpoint->GetDirection(), &direction) || 781 !ConvertSynchronizationTypeSafely( 782 endpoint->GetSynchronizationType(), &synchronization) || 783 !ConvertUsageTypeSafely(endpoint->GetUsageType(), &usage)) { 784 SetError(kErrorCannotListInterfaces); 785 AsyncWorkCompleted(); 786 return; 787 } 788 789 endpoint_desc->address = endpoint->GetAddress(); 790 endpoint_desc->type = type; 791 endpoint_desc->direction = direction; 792 endpoint_desc->maximum_packet_size = endpoint->GetMaximumPacketSize(); 793 endpoint_desc->synchronization = synchronization; 794 endpoint_desc->usage = usage; 795 796 int* polling_interval = new int; 797 endpoint_desc->polling_interval.reset(polling_interval); 798 *polling_interval = endpoint->GetPollingInterval(); 799 800 endpoints.push_back(endpoint_desc); 801 } 802 803 result_->Append(PopulateInterfaceDescriptor( 804 descriptor->GetInterfaceNumber(), 805 descriptor->GetAlternateSetting(), 806 descriptor->GetInterfaceClass(), 807 descriptor->GetInterfaceSubclass(), 808 descriptor->GetInterfaceProtocol(), 809 &endpoints)); 810 } 811 } 812 813 SetResult(result_.release()); 814 AsyncWorkCompleted(); 815 } 816 817 bool UsbListInterfacesFunction::ConvertDirectionSafely( 818 const UsbEndpointDirection& input, 819 usb::Direction* output) { 820 const bool converted = ConvertDirectionToApi(input, output); 821 if (!converted) 822 SetError(kErrorConvertDirection); 823 return converted; 824 } 825 826 bool UsbListInterfacesFunction::ConvertSynchronizationTypeSafely( 827 const UsbSynchronizationType& input, 828 usb::SynchronizationType* output) { 829 const bool converted = ConvertSynchronizationTypeToApi(input, output); 830 if (!converted) 831 SetError(kErrorConvertSynchronizationType); 832 return converted; 833 } 834 835 bool UsbListInterfacesFunction::ConvertTransferTypeSafely( 836 const UsbTransferType& input, 837 usb::TransferType* output) { 838 const bool converted = ConvertTransferTypeToApi(input, output); 839 if (!converted) 840 SetError(kErrorConvertTransferType); 841 return converted; 842 } 843 844 bool UsbListInterfacesFunction::ConvertUsageTypeSafely( 845 const UsbUsageType& input, 846 usb::UsageType* output) { 847 const bool converted = ConvertUsageTypeToApi(input, output); 848 if (!converted) 849 SetError(kErrorConvertUsageType); 850 return converted; 851 } 852 853 UsbCloseDeviceFunction::UsbCloseDeviceFunction() {} 854 855 UsbCloseDeviceFunction::~UsbCloseDeviceFunction() {} 856 857 bool UsbCloseDeviceFunction::Prepare() { 858 parameters_ = CloseDevice::Params::Create(*args_); 859 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 860 return true; 861 } 862 863 void UsbCloseDeviceFunction::AsyncWorkStart() { 864 scoped_refptr<UsbDeviceHandle> device_handle = 865 GetDeviceHandleOrCompleteWithError(parameters_->handle); 866 if (!device_handle) return; 867 868 device_handle->Close(); 869 RemoveUsbDeviceResource(parameters_->handle.handle); 870 AsyncWorkCompleted(); 871 } 872 873 UsbClaimInterfaceFunction::UsbClaimInterfaceFunction() {} 874 875 UsbClaimInterfaceFunction::~UsbClaimInterfaceFunction() {} 876 877 bool UsbClaimInterfaceFunction::Prepare() { 878 parameters_ = ClaimInterface::Params::Create(*args_); 879 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 880 return true; 881 } 882 883 void UsbClaimInterfaceFunction::AsyncWorkStart() { 884 scoped_refptr<UsbDeviceHandle> device_handle = 885 GetDeviceHandleOrCompleteWithError(parameters_->handle); 886 if (!device_handle) return; 887 888 bool success = device_handle->ClaimInterface(parameters_->interface_number); 889 890 if (!success) 891 SetError(kErrorCannotClaimInterface); 892 AsyncWorkCompleted(); 893 } 894 895 UsbReleaseInterfaceFunction::UsbReleaseInterfaceFunction() {} 896 897 UsbReleaseInterfaceFunction::~UsbReleaseInterfaceFunction() {} 898 899 bool UsbReleaseInterfaceFunction::Prepare() { 900 parameters_ = ReleaseInterface::Params::Create(*args_); 901 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 902 return true; 903 } 904 905 void UsbReleaseInterfaceFunction::AsyncWorkStart() { 906 scoped_refptr<UsbDeviceHandle> device_handle = 907 GetDeviceHandleOrCompleteWithError(parameters_->handle); 908 if (!device_handle) return; 909 910 bool success = device_handle->ReleaseInterface(parameters_->interface_number); 911 if (!success) 912 SetError(kErrorCannotReleaseInterface); 913 AsyncWorkCompleted(); 914 } 915 916 UsbSetInterfaceAlternateSettingFunction:: 917 UsbSetInterfaceAlternateSettingFunction() {} 918 919 UsbSetInterfaceAlternateSettingFunction:: 920 ~UsbSetInterfaceAlternateSettingFunction() {} 921 922 bool UsbSetInterfaceAlternateSettingFunction::Prepare() { 923 parameters_ = SetInterfaceAlternateSetting::Params::Create(*args_); 924 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 925 return true; 926 } 927 928 void UsbSetInterfaceAlternateSettingFunction::AsyncWorkStart() { 929 scoped_refptr<UsbDeviceHandle> device_handle = 930 GetDeviceHandleOrCompleteWithError(parameters_->handle); 931 if (!device_handle) return; 932 933 bool success = device_handle->SetInterfaceAlternateSetting( 934 parameters_->interface_number, 935 parameters_->alternate_setting); 936 if (!success) 937 SetError(kErrorCannotSetInterfaceAlternateSetting); 938 939 AsyncWorkCompleted(); 940 } 941 942 UsbControlTransferFunction::UsbControlTransferFunction() {} 943 944 UsbControlTransferFunction::~UsbControlTransferFunction() {} 945 946 bool UsbControlTransferFunction::Prepare() { 947 parameters_ = ControlTransfer::Params::Create(*args_); 948 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 949 return true; 950 } 951 952 void UsbControlTransferFunction::AsyncWorkStart() { 953 scoped_refptr<UsbDeviceHandle> device_handle = 954 GetDeviceHandleOrCompleteWithError(parameters_->handle); 955 if (!device_handle) return; 956 957 const ControlTransferInfo& transfer = parameters_->transfer_info; 958 959 UsbEndpointDirection direction; 960 UsbDeviceHandle::TransferRequestType request_type; 961 UsbDeviceHandle::TransferRecipient recipient; 962 size_t size = 0; 963 964 if (!ConvertDirectionSafely(transfer.direction, &direction) || 965 !ConvertRequestTypeSafely(transfer.request_type, &request_type) || 966 !ConvertRecipientSafely(transfer.recipient, &recipient)) { 967 AsyncWorkCompleted(); 968 return; 969 } 970 971 if (!GetTransferSize(transfer, &size)) { 972 CompleteWithError(kErrorInvalidTransferLength); 973 return; 974 } 975 976 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer( 977 transfer, direction, size); 978 if (!buffer.get()) { 979 CompleteWithError(kErrorMalformedParameters); 980 return; 981 } 982 983 device_handle->ControlTransfer( 984 direction, 985 request_type, 986 recipient, 987 transfer.request, 988 transfer.value, 989 transfer.index, 990 buffer.get(), 991 size, 992 0, 993 base::Bind(&UsbControlTransferFunction::OnCompleted, this)); 994 } 995 996 UsbBulkTransferFunction::UsbBulkTransferFunction() {} 997 998 UsbBulkTransferFunction::~UsbBulkTransferFunction() {} 999 1000 bool UsbBulkTransferFunction::Prepare() { 1001 parameters_ = BulkTransfer::Params::Create(*args_); 1002 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 1003 return true; 1004 } 1005 1006 void UsbBulkTransferFunction::AsyncWorkStart() { 1007 scoped_refptr<UsbDeviceHandle> device_handle = 1008 GetDeviceHandleOrCompleteWithError(parameters_->handle); 1009 if (!device_handle) return; 1010 1011 const GenericTransferInfo& transfer = parameters_->transfer_info; 1012 1013 UsbEndpointDirection direction; 1014 size_t size = 0; 1015 1016 if (!ConvertDirectionSafely(transfer.direction, &direction)) { 1017 AsyncWorkCompleted(); 1018 return; 1019 } 1020 1021 if (!GetTransferSize(transfer, &size)) { 1022 CompleteWithError(kErrorInvalidTransferLength); 1023 return; 1024 } 1025 1026 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer( 1027 transfer, direction, size); 1028 if (!buffer.get()) { 1029 CompleteWithError(kErrorMalformedParameters); 1030 return; 1031 } 1032 1033 device_handle->BulkTransfer( 1034 direction, 1035 transfer.endpoint, 1036 buffer.get(), 1037 size, 1038 0, 1039 base::Bind(&UsbBulkTransferFunction::OnCompleted, this)); 1040 } 1041 1042 UsbInterruptTransferFunction::UsbInterruptTransferFunction() {} 1043 1044 UsbInterruptTransferFunction::~UsbInterruptTransferFunction() {} 1045 1046 bool UsbInterruptTransferFunction::Prepare() { 1047 parameters_ = InterruptTransfer::Params::Create(*args_); 1048 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 1049 return true; 1050 } 1051 1052 void UsbInterruptTransferFunction::AsyncWorkStart() { 1053 scoped_refptr<UsbDeviceHandle> device_handle = 1054 GetDeviceHandleOrCompleteWithError(parameters_->handle); 1055 if (!device_handle) return; 1056 1057 const GenericTransferInfo& transfer = parameters_->transfer_info; 1058 1059 UsbEndpointDirection direction; 1060 size_t size = 0; 1061 1062 if (!ConvertDirectionSafely(transfer.direction, &direction)) { 1063 AsyncWorkCompleted(); 1064 return; 1065 } 1066 1067 if (!GetTransferSize(transfer, &size)) { 1068 CompleteWithError(kErrorInvalidTransferLength); 1069 return; 1070 } 1071 1072 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer( 1073 transfer, direction, size); 1074 if (!buffer.get()) { 1075 CompleteWithError(kErrorMalformedParameters); 1076 return; 1077 } 1078 1079 device_handle->InterruptTransfer( 1080 direction, 1081 transfer.endpoint, 1082 buffer.get(), 1083 size, 1084 0, 1085 base::Bind(&UsbInterruptTransferFunction::OnCompleted, this)); 1086 } 1087 1088 UsbIsochronousTransferFunction::UsbIsochronousTransferFunction() {} 1089 1090 UsbIsochronousTransferFunction::~UsbIsochronousTransferFunction() {} 1091 1092 bool UsbIsochronousTransferFunction::Prepare() { 1093 parameters_ = IsochronousTransfer::Params::Create(*args_); 1094 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 1095 return true; 1096 } 1097 1098 void UsbIsochronousTransferFunction::AsyncWorkStart() { 1099 scoped_refptr<UsbDeviceHandle> device_handle = 1100 GetDeviceHandleOrCompleteWithError(parameters_->handle); 1101 if (!device_handle) return; 1102 1103 const IsochronousTransferInfo& transfer = parameters_->transfer_info; 1104 const GenericTransferInfo& generic_transfer = transfer.transfer_info; 1105 1106 size_t size = 0; 1107 UsbEndpointDirection direction; 1108 1109 if (!ConvertDirectionSafely(generic_transfer.direction, &direction)) { 1110 AsyncWorkCompleted(); 1111 return; 1112 } 1113 if (!GetTransferSize(generic_transfer, &size)) { 1114 CompleteWithError(kErrorInvalidTransferLength); 1115 return; 1116 } 1117 if (transfer.packets < 0 || transfer.packets >= kMaxPackets) { 1118 CompleteWithError(kErrorInvalidNumberOfPackets); 1119 return; 1120 } 1121 unsigned int packets = transfer.packets; 1122 if (transfer.packet_length < 0 || 1123 transfer.packet_length >= kMaxPacketLength) { 1124 CompleteWithError(kErrorInvalidPacketLength); 1125 return; 1126 } 1127 unsigned int packet_length = transfer.packet_length; 1128 const uint64 total_length = packets * packet_length; 1129 if (packets > size || total_length > size) { 1130 CompleteWithError(kErrorTransferLength); 1131 return; 1132 } 1133 1134 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer( 1135 generic_transfer, direction, size); 1136 if (!buffer.get()) { 1137 CompleteWithError(kErrorMalformedParameters); 1138 return; 1139 } 1140 1141 device_handle->IsochronousTransfer( 1142 direction, 1143 generic_transfer.endpoint, 1144 buffer.get(), 1145 size, 1146 packets, 1147 packet_length, 1148 0, 1149 base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this)); 1150 } 1151 1152 UsbResetDeviceFunction::UsbResetDeviceFunction() {} 1153 1154 UsbResetDeviceFunction::~UsbResetDeviceFunction() {} 1155 1156 bool UsbResetDeviceFunction::Prepare() { 1157 parameters_ = ResetDevice::Params::Create(*args_); 1158 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); 1159 return true; 1160 } 1161 1162 void UsbResetDeviceFunction::AsyncWorkStart() { 1163 scoped_refptr<UsbDeviceHandle> device_handle = 1164 GetDeviceHandleOrCompleteWithError(parameters_->handle); 1165 if (!device_handle) return; 1166 1167 bool success = device_handle->ResetDevice(); 1168 if (!success) { 1169 device_handle->Close(); 1170 RemoveUsbDeviceResource(parameters_->handle.handle); 1171 SetResult(new base::FundamentalValue(false)); 1172 CompleteWithError(kErrorResetDevice); 1173 return; 1174 } 1175 1176 SetResult(new base::FundamentalValue(true)); 1177 AsyncWorkCompleted(); 1178 } 1179 1180 } // namespace extensions 1181