diff options
author | gdk@chromium.org <gdk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-05 19:29:09 +0000 |
---|---|---|
committer | gdk@chromium.org <gdk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-05 19:29:09 +0000 |
commit | b5fb8afb885035cf884e2202e9a2490c26da590c (patch) | |
tree | 3012accc49d20498fe172fef047e1a6ee6d07ab9 /chrome/browser | |
parent | 10daa7cfd10b72c26852a60e2ab8cf163e7ab924 (diff) | |
download | chromium_src-b5fb8afb885035cf884e2202e9a2490c26da590c.zip chromium_src-b5fb8afb885035cf884e2202e9a2490c26da590c.tar.gz chromium_src-b5fb8afb885035cf884e2202e9a2490c26da590c.tar.bz2 |
Isochronous transfer support for USB extension API.
BUG=130190
TEST=none
Review URL: https://chromiumcodereview.appspot.com/10511017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140579 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/extensions/api/usb/usb_api.cc | 24 | ||||
-rw-r--r-- | chrome/browser/extensions/api/usb/usb_api.h | 17 | ||||
-rw-r--r-- | chrome/browser/extensions/api/usb/usb_device_resource.cc | 22 | ||||
-rw-r--r-- | chrome/browser/extensions/api/usb/usb_device_resource.h | 2 | ||||
-rw-r--r-- | chrome/browser/usb/usb_device.cc | 34 | ||||
-rw-r--r-- | chrome/browser/usb/usb_device.h | 20 |
6 files changed, 104 insertions, 15 deletions
diff --git a/chrome/browser/extensions/api/usb/usb_api.cc b/chrome/browser/extensions/api/usb/usb_api.cc index 124ce95..8975c72 100644 --- a/chrome/browser/extensions/api/usb/usb_api.cc +++ b/chrome/browser/extensions/api/usb/usb_api.cc @@ -20,6 +20,8 @@ namespace ControlTransfer = extensions::api::experimental_usb::ControlTransfer; namespace FindDevice = extensions::api::experimental_usb::FindDevice; namespace InterruptTransfer = extensions::api::experimental_usb::InterruptTransfer; +namespace IsochronousTransfer = + extensions::api::experimental_usb::IsochronousTransfer; using extensions::api::experimental_usb::Device; using std::vector; @@ -146,4 +148,26 @@ bool UsbInterruptTransferFunction::Respond() { return true; } +UsbIsochronousTransferFunction::UsbIsochronousTransferFunction() {} + +UsbIsochronousTransferFunction::~UsbIsochronousTransferFunction() {} + +bool UsbIsochronousTransferFunction::Prepare() { + parameters_ = IsochronousTransfer::Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(parameters_.get()); + return true; +} + +void UsbIsochronousTransferFunction::Work() { + UsbDeviceResource* const device = controller()->GetUsbDeviceResource( + parameters_->device.handle); + if (device) { + device->IsochronousTransfer(parameters_->transfer_info); + } +} + +bool UsbIsochronousTransferFunction::Respond() { + return true; +} + } // namespace extensions diff --git a/chrome/browser/extensions/api/usb/usb_api.h b/chrome/browser/extensions/api/usb/usb_api.h index 76745ef..2737802 100644 --- a/chrome/browser/extensions/api/usb/usb_api.h +++ b/chrome/browser/extensions/api/usb/usb_api.h @@ -100,6 +100,23 @@ class UsbInterruptTransferFunction : public AsyncAPIFunction { parameters_; }; +class UsbIsochronousTransferFunction : public AsyncAPIFunction { + public: + DECLARE_EXTENSION_FUNCTION_NAME("experimental.usb.isochronousTransfer"); + + UsbIsochronousTransferFunction(); + + protected: + virtual ~UsbIsochronousTransferFunction(); + virtual bool Prepare() OVERRIDE; + virtual void Work() OVERRIDE; + virtual bool Respond() OVERRIDE; + + private: + scoped_ptr<extensions::api::experimental_usb::IsochronousTransfer::Params> + parameters_; +}; + } // namespace extensions #endif // CHROME_BROWSER_EXTENSIONS_API_USB_USB_API_H_ diff --git a/chrome/browser/extensions/api/usb/usb_device_resource.cc b/chrome/browser/extensions/api/usb/usb_device_resource.cc index ab03a3e..9efe3a6 100644 --- a/chrome/browser/extensions/api/usb/usb_device_resource.cc +++ b/chrome/browser/extensions/api/usb/usb_device_resource.cc @@ -17,6 +17,7 @@ using extensions::api::experimental_usb::ControlTransferInfo; using extensions::api::experimental_usb::GenericTransferInfo; +using extensions::api::experimental_usb::IsochronousTransferInfo; using std::string; using std::vector; @@ -183,6 +184,27 @@ void UsbDeviceResource::BulkTransfer(const GenericTransferInfo& transfer) { base::Unretained(this), buffer, size)); } +void UsbDeviceResource::IsochronousTransfer( + const IsochronousTransferInfo& transfer) { + const GenericTransferInfo& generic_transfer = transfer.transfer_info; + + unsigned int size; + UsbDevice::TransferDirection direction; + scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer( + generic_transfer); + + if (!ConvertDirection(generic_transfer.direction, &direction) || + !GetTransferSize(generic_transfer, &size) || !buffer) { + LOG(INFO) << "Malformed transfer parameters."; + return; + } + + device_->IsochronousTransfer(direction, generic_transfer.endpoint, buffer, + size, transfer.packets, transfer.packet_length, 0, base::Bind( + &UsbDeviceResource::TransferComplete, base::Unretained(this), buffer, + size)); +} + void UsbDeviceResource::TransferComplete(net::IOBuffer* buffer, const size_t length, int success) { diff --git a/chrome/browser/extensions/api/usb/usb_device_resource.h b/chrome/browser/extensions/api/usb/usb_device_resource.h index 427df27..27baf04 100644 --- a/chrome/browser/extensions/api/usb/usb_device_resource.h +++ b/chrome/browser/extensions/api/usb/usb_device_resource.h @@ -41,6 +41,8 @@ class UsbDeviceResource : public APIResource { void InterruptTransfer( const api::experimental_usb::GenericTransferInfo& transfer); void BulkTransfer(const api::experimental_usb::GenericTransferInfo& transfer); + void IsochronousTransfer( + const api::experimental_usb::IsochronousTransferInfo& transfer); private: // Invoked by the underlying device's transfer callbacks. Indicates transfer diff --git a/chrome/browser/usb/usb_device.cc b/chrome/browser/usb/usb_device.cc index b3ae7ce..519b72e 100644 --- a/chrome/browser/usb/usb_device.cc +++ b/chrome/browser/usb/usb_device.cc @@ -113,8 +113,7 @@ void UsbDevice::ControlTransfer(const TransferDirection direction, libusb_fill_control_transfer(transfer, handle_, reinterpret_cast<uint8*>( buffer->data()), reinterpret_cast<libusb_transfer_cb_fn>( &HandleTransferCompletion), this, timeout); - AddTransfer(transfer, buffer, callback); - libusb_submit_transfer(transfer); + SubmitTransfer(transfer, buffer, callback); } void UsbDevice::BulkTransfer(const TransferDirection direction, @@ -128,8 +127,7 @@ void UsbDevice::BulkTransfer(const TransferDirection direction, reinterpret_cast<uint8*>(buffer->data()), length, reinterpret_cast<libusb_transfer_cb_fn>(&HandleTransferCompletion), this, timeout); - AddTransfer(transfer, buffer, callback); - libusb_submit_transfer(transfer); + SubmitTransfer(transfer, buffer, callback); } void UsbDevice::InterruptTransfer(const TransferDirection direction, @@ -143,17 +141,35 @@ void UsbDevice::InterruptTransfer(const TransferDirection direction, reinterpret_cast<uint8*>(buffer->data()), length, reinterpret_cast<libusb_transfer_cb_fn>(&HandleTransferCompletion), this, timeout); - AddTransfer(transfer, buffer, callback); - libusb_submit_transfer(transfer); + SubmitTransfer(transfer, buffer, callback); +} + +void UsbDevice::IsochronousTransfer(const TransferDirection direction, + const uint8 endpoint, net::IOBuffer* buffer, const size_t length, + const unsigned int packets, const unsigned int packet_length, + const unsigned int timeout, const net::CompletionCallback& callback) { + CheckDevice(); + + struct libusb_transfer* const transfer = libusb_alloc_transfer(packets); + const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint; + libusb_fill_iso_transfer(transfer, handle_, new_endpoint, + reinterpret_cast<uint8*>(buffer->data()), length, packets, + reinterpret_cast<libusb_transfer_cb_fn>(&HandleTransferCompletion), this, + timeout); + libusb_set_iso_packet_lengths(transfer, packet_length); + + SubmitTransfer(transfer, buffer, callback); } void UsbDevice::CheckDevice() { DCHECK(handle_) << "Device is already closed."; } -void UsbDevice::AddTransfer(PlatformUsbTransferHandle handle, - net::IOBuffer* buffer, - const net::CompletionCallback& callback) { +void UsbDevice::SubmitTransfer(PlatformUsbTransferHandle handle, + net::IOBuffer* buffer, + const net::CompletionCallback& callback) { + libusb_submit_transfer(handle); + Transfer transfer; transfer.buffer = buffer; transfer.callback = callback; diff --git a/chrome/browser/usb/usb_device.h b/chrome/browser/usb/usb_device.h index 6ac4030..7343966 100644 --- a/chrome/browser/usb/usb_device.h +++ b/chrome/browser/usb/usb_device.h @@ -68,6 +68,15 @@ class UsbDevice : public base::RefCounted<UsbDevice> { const unsigned int timeout, const net::CompletionCallback& callback); + void IsochronousTransfer(const TransferDirection direction, + const uint8 endpoint, + net::IOBuffer* buffer, + const size_t length, + const unsigned int packets, + const unsigned int packet_length, + const unsigned int timeout, + const net::CompletionCallback& callback); + // Normal code should not call this function. It is called by the platform's // callback mechanism in such a way that it cannot be made private. Invokes // the callbacks associated with a given transfer, and removes it from the @@ -89,12 +98,11 @@ class UsbDevice : public base::RefCounted<UsbDevice> { // Checks that the device has not yet been closed. void CheckDevice(); - // Starts tracking the USB transfer associated with a platform transfer - // handle. Retains the buffer and copies the completion callback until the - // transfer finishes, whereupon it invokes the callback then releases the - // buffer. - void AddTransfer(PlatformUsbTransferHandle handle, net::IOBuffer* buffer, - const net::CompletionCallback& callback); + // Submits a transfer and starts tracking it. Retains the buffer and copies + // the completion callback until the transfer finishes, whereupon it invokes + // the callback then releases the buffer. + void SubmitTransfer(PlatformUsbTransferHandle handle, net::IOBuffer* buffer, + const net::CompletionCallback& callback); // The UsbService isn't referenced here to prevent a dependency cycle between // the service and the devices. Since a service owns every device, and is |