forked from charlieh0tel/google-libusb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathglibusb.h
229 lines (180 loc) · 7.6 KB
/
glibusb.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
// Copyright 2012 Google Inc. All Rights Reserved.
//
// Wrapper for libusb.
#ifndef _GLIBUSB_GLIBUSB_H_
#define _GLIBUSB_GLIBUSB_H_
#include <stdint.h>
#include <iosfwd>
#include <string>
#include <vector>
#include "glibusb_endpoint.h"
extern "C" {
struct libusb_context;
}
namespace glibusb {
// Structure to hold the physical location on the USB bus of the device.
struct DeviceLocation {
DeviceLocation() : bus_number(0), device_address(0) {}
DeviceLocation(uint8_t new_bus_number, uint8_t new_device_address)
: bus_number(new_bus_number), device_address(new_device_address) {}
bool operator==(const struct DeviceLocation &rhs) const {
return ((bus_number == rhs.bus_number) &&
(device_address == rhs.device_address));
}
std::string ToString() const;
uint8_t bus_number;
uint8_t device_address;
};
// Returns a string representing the DeviceLocation.
std::string DeviceLocationToString(const DeviceLocation &location);
std::ostream &operator <<(std::ostream &out,
const DeviceLocation &location);
// Structure to hold the USB vendor and product ids for a device.
struct VendorProductId {
VendorProductId() : vendor_id(0), product_id(0) {}
VendorProductId(uint16_t new_vendor_id, uint16_t new_product_id)
: vendor_id(new_vendor_id), product_id(new_product_id) {}
bool operator==(const struct VendorProductId &rhs) const {
return ((vendor_id == rhs.vendor_id) &&
(product_id == rhs.product_id));
}
std::string ToString() const;
uint16_t vendor_id;
uint16_t product_id;
};
// Returns a string representing the VendorProductId.
std::string VendorProductIdToString(const VendorProductId &vendor_product_id);
// Structure to hold the location and id of a device. This is enough to
// uniquely identify the device redundantly.
struct DeviceLocationAndId {
DeviceLocationAndId() {}
DeviceLocationAndId(const DeviceLocation &new_location,
const VendorProductId &new_id)
: location(new_location), id(new_id)
{}
bool operator==(const struct DeviceLocationAndId &rhs) const {
return ((location == rhs.location) &&
(id == rhs.id));
}
std::string ToString() const;
DeviceLocation location;
VendorProductId id;
};
// Returns a string representing the DeviceLocation and provides a stream
// operator for logging.
std::string DeviceLocationAndIdToString(const DeviceLocationAndId &location_and_id);
std::ostream &operator <<(std::ostream &out,
const DeviceLocationAndId &location_and_id);
// Provides an interface to an individual USB device.
class UsbDevice {
public:
explicit UsbDevice(VendorProductId vendor_product_id)
: vendor_product_id_(vendor_product_id) {}
virtual ~UsbDevice() {}
// Activates an alternate setting; returns true on success.
bool SetAlternateSetting(int setting) {
return DoSetAlternateSetting(setting);
}
// Returns the first endpoint to match the direction and transfer types.
// Caller is responsible for freeing the endpoint.
UsbInEndpoint *FindInEndpoint(UsbEndpoint::TransferType endpoint) {
return DoFindInEndpoint(endpoint);
}
UsbOutEndpoint *FindOutEndpoint(UsbEndpoint::TransferType endpoint) {
return DoFindOutEndpoint(endpoint);
}
// Returns the endpoint at the specified address.
// Caller is responsible for freeing the endpoint.
// Virtual for testing.
UsbInEndpoint *InEndpoint(int number) { return DoInEndpoint(number); }
UsbOutEndpoint *OutEndpoint(int number) { return DoOutEndpoint(number); }
// Returns the vendor and product ids.
VendorProductId GetVendorAndProductId() { return vendor_product_id_; }
struct DeviceLocationAndId Id() { return DoDeviceLocationAndId(); }
protected:
VendorProductId vendor_product_id_;
private:
friend class Libusb; // For private constructor.
virtual bool DoSetAlternateSetting(int setting) = 0;
virtual UsbInEndpoint *DoFindInEndpoint(
UsbEndpoint::TransferType endpoint) = 0;
virtual UsbOutEndpoint *DoFindOutEndpoint(
UsbEndpoint::TransferType endpoint) = 0;
virtual UsbInEndpoint *DoInEndpoint(int number) = 0;
virtual UsbOutEndpoint *DoOutEndpoint(int number) = 0;
virtual struct DeviceLocationAndId DoDeviceLocationAndId() = 0;
UsbDevice(const UsbDevice &) = delete;
void operator=(const UsbDevice &) = delete;
};
// Provides RAII-style libusb initialization.
class Libusb {
public:
Libusb();
~Libusb();
// Sets the debug level.
void SetDebug(int level);
// Returns the locations, vendor ids, and product ids of all attached devices.
void FindDeviceLocationAndId(std::vector<DeviceLocationAndId> *result);
// Finds and returns exactly one device with the matching vendor and
// product ID or CHECKs.
UsbDevice *FindSingleMatchingDeviceOrLose(const VendorProductId &id);
// Does the same, but returns NULL on failure rather than CHECKing.
UsbDevice *FindSingleMatchingDevice(const VendorProductId &id);
// Finds and returns exactly one device with the matching vendor and
// product ID, at the specified bus number and device address, or CHECKs.
UsbDevice *FindSingleMatchingDeviceAtLocationOrLose(
const DeviceLocationAndId &dev_location_id);
// Does the same, but returns NULL on failure rather than CHECKing.
UsbDevice *FindSingleMatchingDeviceAtLocation(
const DeviceLocationAndId &dev_location_id);
// Finds exactly one device that matches whatever parameters were specified,
// or CHECKs.
//
// Args:
// target_vendor_product_id: a vendor/product ID pair to search for,
// or empty string.
// target_device_location: a device location to search for, or empty string.
// [out] dev_location_id: The location and Ids of the chosen device.
void FindDeviceBySpecification(
const std::string &target_vendor_product_id,
const std::string &target_device_location,
DeviceLocationAndId *dev_location_id);
// Finds exactly one device matching the specified parameters or checks.
//
// Args:
// target_ids: a list of product and vendor ids that match.
// target_device_location: a string with the device location, or an empty
// string to search all locations.
// [out] dev_location_id: The location and Ids of the chosen device.
void FindSingleDeviceMatchingTargetId(
const VendorProductId &target_id,
const std::string &target_device_location,
DeviceLocationAndId *dev_location_id);
// Finds exactly one device matching the specified parameters or checks.
//
// Args:
// target_ids: a list of product and vendor ids that match.
// target_device_location: a string with the device location, or an empty
// string to search all locations.
// [out] dev_location_id: The location and Ids of the chosen device.
void FindSingleDeviceMatchingTargetIds(
const std::vector<VendorProductId> &target_ids,
const std::string &target_device_location,
DeviceLocationAndId *dev_location_id);
// Parses a vendor id and product id string, and appends the result on
// target_ids.
// The string must be in the form VVVV:PPPP, where VVVV is a 4-digit hex
// vendor id and PPPP is a 4-digit hex product id.
static void ParseProductVendorString(const std::string &target_vendor_product_id,
std::vector<VendorProductId> *target_ids);
static void ParseDeviceLocationString(const std::string &target_device_location,
DeviceLocation *location);
// TODO(charliehotel): add richer ways to retrieve device handles.
private:
// Libusb handle
struct libusb_context *libusb_context_;
Libusb(const Libusb &) = delete;
void operator=(const Libusb &) = delete;
};
} // namespace glibusb
#endif // _GLIBUSB_GLIBUSB_H_