blob: 6056c6608651d425e5458847ebdad4baa69a0904 [file] [log] [blame]
Austin Schuh9b360e92013-03-27 04:47:04 +00001#ifndef LIBUSB_H_
2#define LIBUSB_H_
3
Brian Silverman798c7782013-03-28 16:48:02 -07004#include <libusb-1.0/libusb.h>
Austin Schuh9b360e92013-03-27 04:47:04 +00005
Brian Silverman4ad17832013-03-31 01:26:08 -07006#include "aos/common/macros.h"
Brian Silverman4bde0172013-10-25 15:53:25 -07007#include "aos/common/time.h"
Brian Silverman4ad17832013-03-31 01:26:08 -07008
Austin Schuh9b360e92013-03-27 04:47:04 +00009class LibUSBDeviceHandle;
Brian Silverman4ad17832013-03-31 01:26:08 -070010namespace libusb {
11class Transfer;
Brian Silvermanc554a8f2013-03-31 19:07:49 -070012class IsochronousTransfer;
Brian Silverman4ad17832013-03-31 01:26:08 -070013}
Austin Schuh9b360e92013-03-27 04:47:04 +000014
15class LibUSB {
16 public:
17 explicit LibUSB();
Brian Silverman4ad17832013-03-31 01:26:08 -070018 ~LibUSB();
19
Austin Schuh9b360e92013-03-27 04:47:04 +000020 // Return a device handle or NULL with the correct VID and PID.
21 LibUSBDeviceHandle *FindDeviceWithVIDPID(
22 int vid, int pid);
23
Brian Silverman4ad17832013-03-31 01:26:08 -070024 void HandleEvents();
25
Austin Schuh9b360e92013-03-27 04:47:04 +000026 private:
27 libusb_context *ctx_;
Brian Silverman4ad17832013-03-31 01:26:08 -070028
29 DISALLOW_COPY_AND_ASSIGN(LibUSB);
Austin Schuh9b360e92013-03-27 04:47:04 +000030};
31
32class LibUSBDeviceHandle {
33 public:
34 virtual ~LibUSBDeviceHandle();
35 // Transfers data using an interrupt transfer.
36 int interrupt_transfer(unsigned char endpoint, unsigned char *data,
37 int length, int *transferred, unsigned int timeout);
38
39 // Transfers data using a bulk transfer.
40 int bulk_transfer(unsigned char endpoint, unsigned char *data,
41 int length, int *transferred, unsigned int timeout);
42
43 private:
44 friend class LibUSB; // For constructor
Brian Silverman4ad17832013-03-31 01:26:08 -070045 friend class libusb::Transfer; // for access to dev_handle_
Brian Silvermanc554a8f2013-03-31 19:07:49 -070046 friend class libusb::IsochronousTransfer; // for access to dev_handle_
Austin Schuh9b360e92013-03-27 04:47:04 +000047 // Takes ownership of the device handle and frees it when destructed.
48 explicit LibUSBDeviceHandle(libusb_device_handle *dev_handle);
Brian Silverman4ad17832013-03-31 01:26:08 -070049 libusb_device_handle *dev_handle_;
50
51 DISALLOW_COPY_AND_ASSIGN(LibUSBDeviceHandle);
Austin Schuh9b360e92013-03-27 04:47:04 +000052};
53
Brian Silverman4ad17832013-03-31 01:26:08 -070054// TODO(brians): move everything in here
55namespace libusb {
56
57// Wraps a libusb_transfer*.
58// Represents an asynchronous transfer.
59// Only designed to support interrupt and bulk transfers because they are very
60// similar and simple.
61class Transfer {
62 public:
63 Transfer(size_t data_length,
64 void (*callback)(Transfer *, void *),
Brian Silverman4bde0172013-10-25 15:53:25 -070065 void *user_data,
66 int num_iso_packets = 0);
Brian Silverman4ad17832013-03-31 01:26:08 -070067 ~Transfer();
68
69 void FillInterrupt(LibUSBDeviceHandle *device,
70 unsigned char endpoint,
71 unsigned int timeout);
72
73 void Submit();
74 void Cancel();
75
76 libusb_transfer_status status() { return transfer_->status; }
Brian Silverman4bde0172013-10-25 15:53:25 -070077 virtual int read_bytes() { return transfer_->actual_length; }
Brian Silverman4ad17832013-03-31 01:26:08 -070078
79 const uint8_t *data() { return data_; }
80
Brian Silvermanc554a8f2013-03-31 19:07:49 -070081 protected:
Brian Silverman4ad17832013-03-31 01:26:08 -070082 static void StaticTransferCallback(libusb_transfer *self) {
83 static_cast<Transfer *>(self->user_data)->TransferCallback();
84 }
Brian Silvermanc554a8f2013-03-31 19:07:49 -070085
Brian Silverman4bde0172013-10-25 15:53:25 -070086 protected:
Brian Silverman4ad17832013-03-31 01:26:08 -070087 libusb_transfer *const transfer_;
88
89 uint8_t *const data_;
90 size_t data_length_;
91
Brian Silverman4bde0172013-10-25 15:53:25 -070092 private:
93 void TransferCallback();
94
Brian Silverman4ad17832013-03-31 01:26:08 -070095 void (*const callback_)(Transfer *, void *);
96 void *const user_data_;
97
98 DISALLOW_COPY_AND_ASSIGN(Transfer);
99};
100
Brian Silverman4bde0172013-10-25 15:53:25 -0700101// TODO(brians): Make this actually work for num_packets != 1.
Brian Silvermanc554a8f2013-03-31 19:07:49 -0700102class IsochronousTransfer : public Transfer {
103 public:
104 IsochronousTransfer(size_t packet_length,
105 int num_packets,
106 void (*callback)(Transfer *, void *),
107 void *user_data);
108
109 void FillIsochronous(LibUSBDeviceHandle *device,
110 unsigned char endpoint,
Brian Silverman4bde0172013-10-25 15:53:25 -0700111 const ::aos::time::Time &timeout);
112
113 virtual int read_bytes() {
114 return transfer_->iso_packet_desc[0].actual_length;
115 }
Brian Silvermanc554a8f2013-03-31 19:07:49 -0700116
117 private:
118 const int num_packets_;
119};
120
Brian Silverman4ad17832013-03-31 01:26:08 -0700121} // namespace libusb
122
Austin Schuh9b360e92013-03-27 04:47:04 +0000123#endif // LIBUSB_H_