Bumped copyright dates for 2013
[barry.git] / src / usbwrap.h
blobc7b6d4d6f25b55913b529cc520d4fca9d26ff5dd
1 ///
2 /// \file usbwrap.h
3 /// USB API wrapper
4 ///
6 /*
7 Copyright (C) 2005-2013, Chris Frey
8 Portions Copyright (C) 2011, RealVNC Ltd.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License in the COPYING file at the
20 root directory of this project for more details.
24 #ifndef __SB_USBWRAP_H__
25 #define __SB_USBWRAP_H__
27 #include "dll.h"
29 #include <memory>
30 #include <tr1/memory>
31 #include <vector>
32 #include <map>
33 #include "error.h"
35 #define USBWRAP_DEFAULT_TIMEOUT 30000
37 // Matches any product ID when calling DeviceList::MatchDevices
38 #define PRODUCT_ANY 0x10000
39 // Indicates an unknown product ID
40 #define PRODUCT_UNKNOWN 0x20000
42 namespace Barry { class Data; }
44 /// Namespace for the libusb-related wrapper classes. This namespace
45 /// may change in the future.
46 namespace Usb {
48 /// \addtogroup exceptions
49 /// @{
51 /// Thrown on low level USB errors.
52 class BXEXPORT Error : public Barry::Error
54 int m_libusb_errcode;
56 public:
57 Error(const std::string &str);
58 Error(int libusb_errcode, const std::string &str);
60 // can return 0 in some case, if unknown error code
61 int libusb_errcode() const { return m_libusb_errcode; }
63 // returns a translated system error code when using libusb 1.0
64 // returns 0 if unknown or unable to translate
65 int system_errcode() const;
68 class BXEXPORT Timeout : public Error
70 public:
71 Timeout(const std::string &str);
72 Timeout(int errcode, const std::string &str);
75 /// @}
77 // Private struct for holding library specific
78 // a unique identifier to a connected device.
79 class DeviceIDImpl;
81 class BXEXPORT DeviceID
83 public:
84 std::tr1::shared_ptr<DeviceIDImpl> m_impl;
85 public:
86 // Takes ownership of impl
87 DeviceID(DeviceIDImpl* impl = NULL);
88 ~DeviceID();
89 const char* GetBusName() const;
90 uint16_t GetNumber() const;
91 const char* GetFilename() const;
92 uint16_t GetIdProduct() const;
94 // Utility function: returns a string that uniquely identifies
95 // the bus and device, regardless of which libusb you're using
96 std::string GetUsbName() const;
99 // Private struct for holding a library specific
100 // device handle
101 struct DeviceHandle;
103 // Static functions for setting up USB
104 // The interface that usbwrap.cc uses
105 // to interact with the USB library
106 class BXEXPORT LibraryInterface
108 public:
109 static std::string GetLastErrorString(int libusb_errcode);
111 /// Returns 0 if unable to translate libusb error code.
112 /// Note that this function assumes you already know that libusb_errcode
113 /// contains an actual error code, and so returns 0 (success)
114 /// for an unknown error. This means that "success" means error
115 /// if you use this function correctly, but if you pass in a success
116 /// code (>= 0) it will always return 0 as well.
117 static int TranslateErrcode(int libusb_errcode);
119 /// Returns true on success... pass in a pointer to int
120 /// if the low level error code is important to you.
121 static bool Init(int *libusb_errno = 0);
122 static void Uninit();
123 static void SetDataDump(bool data_dump_mode);
126 // Forward declaration of descriptor types.
127 class BXEXPORT DeviceDescriptor;
128 class BXEXPORT ConfigDescriptor;
129 class BXEXPORT InterfaceDescriptor;
131 // Private struct for holding library specific
132 // information about endpoint descriptors
133 struct EndpointDescriptorImpl;
135 // Encapsulates an endpoint descriptor
136 class BXEXPORT EndpointDescriptor
138 public:
139 enum EpType
141 ControlType = 0,
142 IsochronousType = 1,
143 BulkType = 2,
144 InterruptType = 3,
145 InvalidType = 0xff
147 private:
148 const std::auto_ptr<EndpointDescriptorImpl> m_impl;
149 bool m_read;
150 uint8_t m_addr;
151 EpType m_type;
152 private:
153 EndpointDescriptor(const EndpointDescriptor& rhs); // Prevent copying
154 public:
155 EndpointDescriptor(InterfaceDescriptor& dev, int endpoint);
156 ~EndpointDescriptor();
157 bool IsRead() const;
158 uint8_t GetAddress() const;
159 EpType GetType() const;
162 // Private struct for holding library specific
163 // information about interface descriptors
164 struct InterfaceDescriptorImpl;
166 // Encapsulates an interface descriptor
168 // The inherited vector methods look up endpoints
169 class BXEXPORT InterfaceDescriptor : public std::vector<EndpointDescriptor*>
171 friend class EndpointDescriptor;
172 public:
173 typedef std::vector<EndpointDescriptor*> base_type;
174 private:
175 const std::auto_ptr<InterfaceDescriptorImpl> m_impl;
176 private:
177 InterfaceDescriptor(const InterfaceDescriptor& rhs); // Prevent copying
178 public:
179 InterfaceDescriptor(ConfigDescriptor& cfgdesc,
180 int iface, int altsetting);
181 ~InterfaceDescriptor();
182 uint8_t GetClass() const;
183 uint8_t GetNumber() const;
184 uint8_t GetAltSetting() const;
187 // Private struct for holding library specific
188 // information about config descriptors
190 struct ConfigDescriptorImpl;
192 // Encapsulates a configuration descriptor
194 // The inherited map methods look up interface descriptors
195 class BXEXPORT ConfigDescriptor : public std::map<int, InterfaceDescriptor*>
197 friend class InterfaceDescriptor;
198 public:
199 typedef std::map<int, InterfaceDescriptor*> base_type;
200 private:
201 const std::auto_ptr<ConfigDescriptorImpl> m_impl;
202 private:
203 ConfigDescriptor(const ConfigDescriptor& rhs); // Prevent copying
204 public:
205 ConfigDescriptor(DeviceDescriptor& dev, int cfgnumber);
206 ~ConfigDescriptor();
207 uint8_t GetNumber() const;
210 // Private struct for holding library specific
211 // information about a device descriptor
212 struct DeviceDescriptorImpl;
214 // Encapsulates a device descriptor
216 // The inherited map methods look up config descriptors
217 class BXEXPORT DeviceDescriptor : public std::map<int, ConfigDescriptor*>
219 friend class ConfigDescriptor;
220 public:
221 typedef std::map<int, ConfigDescriptor*> base_type;
222 private:
223 const std::auto_ptr<DeviceDescriptorImpl> m_impl;
224 private:
225 DeviceDescriptor(const DeviceDescriptor& rhs); // Prevent copying
226 public:
227 DeviceDescriptor(DeviceID& devid);
228 ~DeviceDescriptor();
231 // Private struct for holding library specific
232 // information for devices.
233 struct DeviceListImpl;
235 class BXEXPORT DeviceList
237 private:
238 // Private implementation structure
239 const std::auto_ptr<DeviceListImpl> m_impl;
240 private:
241 DeviceList(const DeviceList& rhs); // Prevent copying
242 public:
243 DeviceList();
244 ~DeviceList();
246 std::vector<DeviceID> MatchDevices(int vendor, int product,
247 const char *busname, const char *devname);
251 struct PrivateDeviceData;
253 class BXEXPORT Device
255 private:
256 Usb::DeviceID m_id;
257 const std::auto_ptr<Usb::DeviceHandle> m_handle;
259 int m_timeout;
260 int m_lasterror;
261 private:
262 Device(const Device& rhs); // Prevent copying
263 public:
264 Device(const Usb::DeviceID& id, int timeout = USBWRAP_DEFAULT_TIMEOUT);
265 ~Device();
267 /////////////////////////////
268 // Data access
270 const Usb::DeviceID& GetID() const { return m_id; }
271 const Usb::DeviceHandle* GetHandle() const { return &*m_handle; }
272 int GetLastError() const { return m_lasterror; } //< not thread safe...
273 //< use the error code stored in the exceptions to track
274 //< errors in threaded usage
275 void SetLastError(int err) { m_lasterror = err; }
276 int GetDefaultTimeout() const { return m_timeout; }
278 /////////////////////////////
279 // Device information
281 int GetPowerLevel();
282 int FindInterface(int ifaceClass);
283 std::string GetSimpleSerialNumber();
285 /////////////////////////////
286 // Device manipulation
288 bool SetConfiguration(unsigned char cfg);
289 bool ClearHalt(int ep);
290 bool Reset();
291 bool IsAttachKernelDriver(int iface);
292 bool DetachKernelDriver(int iface);
294 /////////////////////////////
295 // IO functions
297 bool BulkRead(int ep, Barry::Data &data, int timeout = -1);
298 bool BulkWrite(int ep, const Barry::Data &data, int timeout = -1);
299 bool BulkWrite(int ep, const void *data, size_t size, int timeout = -1);
300 bool InterruptRead(int ep, Barry::Data &data, int timeout = -1);
301 bool InterruptWrite(int ep, const Barry::Data &data, int timeout = -1);
303 void BulkDrain(int ep, int timeout = 100);
305 bool ControlMsg(int requesttype, int request, int value,
306 int index, char *bytes, int size, int timeout);
308 /////////////////////////////
309 // Combo functions
311 bool GetConfiguration(unsigned char &cfg);
314 class BXEXPORT Interface
316 Device &m_dev;
317 int m_iface;
318 public:
319 Interface(Device &dev, int iface);
320 ~Interface();
321 bool SetAltInterface(int altSetting);
324 // Map of Endpoint numbers (not indexes) to endpoint descriptors
325 struct BXEXPORT EndpointPair
327 unsigned char read;
328 unsigned char write;
329 EndpointDescriptor::EpType type;
331 EndpointPair();
332 bool IsTypeSet() const;
333 bool IsComplete() const;
334 bool IsBulk() const;
337 class BXEXPORT EndpointPairings : public std::vector<EndpointPair>
339 public:
340 typedef std::vector<EndpointPair> base_type;
341 private:
342 bool m_valid;
343 public:
344 EndpointPairings(const std::vector<EndpointDescriptor*>& eps);
345 ~EndpointPairings();
346 bool IsValid() const;
349 class BXEXPORT Match
351 private:
352 std::vector<DeviceID> m_list;
353 std::vector<DeviceID>::iterator m_iter;
354 public:
355 // Due to USB libraries having different ownership ideas
356 // about device IDs, Match objects must be constructed
357 // with a device list.
358 Match(DeviceList& devices,
359 int vendor, int product,
360 const char *busname = 0, const char *devname = 0);
361 ~Match();
363 // searches for next match, and if found, fills devid with
364 // something you can pass on to DeviceDiscover, etc
365 // returns true if next is found, false if no more
366 bool next_device(Usb::DeviceID& devid);
371 #endif