| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef DEVICE_USB_USB_DEVICE_HANDLE_USBFS_H_ |
| #define DEVICE_USB_USB_DEVICE_HANDLE_USBFS_H_ |
| |
| #include <list> |
| #include <map> |
| #include <memory> |
| #include <vector> |
| |
| #include "base/files/scoped_file.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/single_thread_task_runner.h" |
| #include "device/usb/usb_device_handle.h" |
| |
| struct usbdevfs_urb; |
| |
| namespace base { |
| class SequencedTaskRunner; |
| class SingleThreadTaskRunner; |
| } |
| |
| namespace device { |
| |
| // Implementation of a USB device handle on top of the Linux USBFS ioctl |
| // interface available on Linux, Chrome OS and Android. |
| class UsbDeviceHandleUsbfs : public UsbDeviceHandle { |
| public: |
| // Constructs a new device handle from an existing |device| and open file |
| // descriptor to that device. |blocking_task_runner| must run tasks on a |
| // thread that supports FileDescriptorWatcher. |
| UsbDeviceHandleUsbfs( |
| scoped_refptr<UsbDevice> device, |
| base::ScopedFD fd, |
| scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); |
| |
| // UsbDeviceHandle implementation. |
| scoped_refptr<UsbDevice> GetDevice() const override; |
| void Close() override; |
| void SetConfiguration(int configuration_value, |
| const ResultCallback& callback) override; |
| void ClaimInterface(int interface_number, |
| const ResultCallback& callback) override; |
| void ReleaseInterface(int interface_number, |
| const ResultCallback& callback) override; |
| void SetInterfaceAlternateSetting(int interface_number, |
| int alternate_setting, |
| const ResultCallback& callback) override; |
| void ResetDevice(const ResultCallback& callback) override; |
| void ClearHalt(uint8_t endpoint, const ResultCallback& callback) override; |
| void ControlTransfer(UsbEndpointDirection direction, |
| TransferRequestType request_type, |
| TransferRecipient recipient, |
| uint8_t request, |
| uint16_t value, |
| uint16_t index, |
| scoped_refptr<net::IOBuffer> buffer, |
| size_t length, |
| unsigned int timeout, |
| const TransferCallback& callback) override; |
| void IsochronousTransferIn( |
| uint8_t endpoint_number, |
| const std::vector<uint32_t>& packet_lengths, |
| unsigned int timeout, |
| const IsochronousTransferCallback& callback) override; |
| void IsochronousTransferOut( |
| uint8_t endpoint_number, |
| scoped_refptr<net::IOBuffer> buffer, |
| const std::vector<uint32_t>& packet_lengths, |
| unsigned int timeout, |
| const IsochronousTransferCallback& callback) override; |
| // To support DevTools this function may be called from any thread and on |
| // completion |callback| will be run on that thread. |
| void GenericTransfer(UsbEndpointDirection direction, |
| uint8_t endpoint_number, |
| scoped_refptr<net::IOBuffer> buffer, |
| size_t length, |
| unsigned int timeout, |
| const TransferCallback& callback) override; |
| const UsbInterfaceDescriptor* FindInterfaceByEndpoint( |
| uint8_t endpoint_address) override; |
| |
| protected: |
| ~UsbDeviceHandleUsbfs() override; |
| |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner() const { |
| return task_runner_; |
| } |
| |
| // Stops |helper_| and releases ownership of |fd_| without closing it. |
| void ReleaseFileDescriptor(); |
| |
| private: |
| class FileThreadHelper; |
| struct Transfer; |
| struct InterfaceInfo { |
| uint8_t alternate_setting; |
| }; |
| struct EndpointInfo { |
| UsbTransferType type; |
| const UsbInterfaceDescriptor* interface; |
| }; |
| |
| virtual void CloseBlocking(); |
| void SetConfigurationBlocking(int configuration_value, |
| const ResultCallback& callback); |
| void SetConfigurationComplete(int configuration_value, |
| bool success, |
| const ResultCallback& callback); |
| void ReleaseInterfaceBlocking(int interface_number, |
| const ResultCallback& callback); |
| void ReleaseInterfaceComplete(int interface_number, |
| const ResultCallback& callback); |
| void SetInterfaceBlocking(int interface_number, |
| int alternate_setting, |
| const ResultCallback& callback); |
| void ResetDeviceBlocking(const ResultCallback& callback); |
| void ClearHaltBlocking(uint8_t endpoint_address, |
| const ResultCallback& callback); |
| void IsochronousTransferInternal(uint8_t endpoint_address, |
| scoped_refptr<net::IOBuffer> buffer, |
| size_t total_length, |
| const std::vector<uint32_t>& packet_lengths, |
| unsigned int timeout, |
| const IsochronousTransferCallback& callback); |
| void GenericTransferInternal( |
| UsbEndpointDirection direction, |
| uint8_t endpoint_number, |
| scoped_refptr<net::IOBuffer> buffer, |
| size_t length, |
| unsigned int timeout, |
| const TransferCallback& callback, |
| scoped_refptr<base::SingleThreadTaskRunner> callback_runner); |
| void ReapedUrbs(const std::vector<usbdevfs_urb*>& urbs); |
| void TransferComplete(std::unique_ptr<Transfer> transfer); |
| void RefreshEndpointInfo(); |
| void ReportIsochronousError( |
| const std::vector<uint32_t>& packet_lengths, |
| const UsbDeviceHandle::IsochronousTransferCallback& callback, |
| UsbTransferStatus status); |
| void SetUpTimeoutCallback(Transfer* transfer, unsigned int timeout); |
| std::unique_ptr<Transfer> RemoveFromTransferList(Transfer* transfer); |
| void CancelTransfer(Transfer* transfer, UsbTransferStatus status); |
| void DiscardUrbBlocking(Transfer* transfer); |
| void UrbDiscarded(Transfer* transfer); |
| |
| scoped_refptr<UsbDevice> device_; |
| base::ScopedFD fd_; |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; |
| |
| // Maps claimed interfaces by interface number to their current alternate |
| // setting. |
| std::map<uint8_t, InterfaceInfo> interfaces_; |
| |
| // Maps endpoints (by endpoint address) to the interface they are a part of. |
| // Only endpoints of currently claimed and selected interface alternates are |
| // included in the map. |
| std::map<uint8_t, EndpointInfo> endpoints_; |
| |
| // Helper object owned by the blocking task thread. It will be freed if that |
| // thread's message loop is destroyed but can also be freed by this class on |
| // destruction. |
| FileThreadHelper* helper_; |
| |
| std::list<std::unique_ptr<Transfer>> transfers_; |
| }; |
| |
| } // namespace device |
| |
| #endif // DEVICE_USB_USB_DEVICE_HANDLE_USBFS_H_ |