summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorgdk@chromium.org <gdk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-05 19:29:09 +0000
committergdk@chromium.org <gdk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-05 19:29:09 +0000
commitb5fb8afb885035cf884e2202e9a2490c26da590c (patch)
tree3012accc49d20498fe172fef047e1a6ee6d07ab9 /chrome/browser
parent10daa7cfd10b72c26852a60e2ab8cf163e7ab924 (diff)
downloadchromium_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.cc24
-rw-r--r--chrome/browser/extensions/api/usb/usb_api.h17
-rw-r--r--chrome/browser/extensions/api/usb/usb_device_resource.cc22
-rw-r--r--chrome/browser/extensions/api/usb/usb_device_resource.h2
-rw-r--r--chrome/browser/usb/usb_device.cc34
-rw-r--r--chrome/browser/usb/usb_device.h20
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