- added boost::serialization to build
[barry.git] / src / usbwrap.h
blobb209f225d0db30a9683b84b49404b981f5dc6bf7
1 ///
2 /// \file usbwrap.h
3 /// USB API wrapper
4 ///
6 /*
7 Copyright (C) 2005, Chris Frey
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
23 #ifndef __SB_USBWRAP_H__
24 #define __SB_USBWRAP_H__
26 #include <libusb.h>
27 #include <vector>
28 #include <stdexcept>
30 #define USBWRAP_DEFAULT_TIMEOUT 10000
32 class Data;
34 /// Namespace for the libusb-related wrapper classes. This namespace
35 /// may change in the future.
36 namespace Usb {
38 /// \addtogroup exceptions
39 /// @{
41 /// Thrown on low level USB errors.
42 class UsbError : public std::runtime_error
44 public:
45 UsbError(const std::string &str) : std::runtime_error(str) {}
48 /// @}
51 class Match
53 libusb_match_handle_t *m_match;
54 int m_lasterror;
55 public:
56 Match(int vendor, int product)
57 : m_match(0)
59 if( libusb_match_devices_by_vendor(&m_match, vendor, product) < 0 )
60 throw UsbError("match failed");
63 ~Match()
65 libusb_free_match(m_match);
68 bool next_device(libusb_device_id_t *devid)
70 m_lasterror = libusb_match_next_device(m_match, devid);
71 return m_lasterror >= 0;
78 class Device;
80 // This class behaves a lot like std::auto_ptr<>, in that only one
81 // object can ever own a given libusb_io_handle_t at a time. The
82 // copy constructors and operator=() make it safe to store in a vector.
83 class IO
85 Device *m_dev;
86 mutable libusb_io_handle_t *m_handle;
88 // helpers
89 void cleanup();
91 IO(Device *dev, libusb_io_handle_t *handle);
92 public:
93 IO(Device &dev, libusb_io_handle_t *handle);
95 // copyable... the copied-to object will contain the handle,
96 // and other will be invalidated
97 IO(const IO &other);
98 IO& operator=(const IO &other);
100 // will cancel if not complete, and will always free if valid
101 ~IO();
104 // operators
105 bool operator==(libusb_io_handle_t *h) const { return m_handle == h; }
107 // if valid, this object contains a pending usb io transfer handle...
108 // when compeleted, canceled, or freed, this will return false
109 bool IsValid() const { return m_handle != 0; }
110 void Forget() { m_handle = 0; }
111 void Free() { cleanup(); }
113 // API wrappers
114 bool IsCompleted() const;
115 void Wait();
116 void Cancel();
117 int GetStatus() const;
118 int GetSize() const;
119 int GetReqSize() const;
120 int GetEndpoint() const;
121 Device& GetDevice() const { return *m_dev; }
122 unsigned char * GetData();
123 const unsigned char * GetData() const;
125 // static helpers for various states
126 static IO InvalidIO() { return IO(0, 0); }
130 // Const IO - used by Device when it wishes to safely expose its list
131 // of tracked IO handles, without letting the caller take ownership
132 class CIO
134 const IO &m_io;
136 public:
137 CIO(const IO &io) : m_io(io) {}
139 // operators
140 bool operator==(libusb_io_handle_t *h) const
141 { return m_io.operator==(h); }
143 // if valid, this object contains a pending usb io transfer handle...
144 // when compeleted, canceled, or freed, this will return false
145 bool IsValid() const { return m_io.IsValid(); }
147 // API wrappers
148 bool IsCompleted() const { return m_io.IsCompleted(); }
149 int GetStatus() const { return m_io.GetStatus();}
150 int GetSize() const { return m_io.GetSize(); }
151 int GetReqSize() const { return m_io.GetReqSize();}
152 int GetEndpoint() const { return m_io.GetEndpoint(); }
153 Device& GetDevice() const { return m_io.GetDevice(); }
154 const unsigned char * GetData() const { return m_io.GetData(); }
159 class Device
161 public:
162 typedef std::vector<IO> io_list_type;
164 private:
165 libusb_device_id_t m_id;
166 libusb_dev_handle_t *m_handle;
168 io_list_type m_ios;
170 int m_timeout;
171 int m_lasterror;
173 public:
174 Device(libusb_device_id_t id)
175 : m_id(id), m_timeout(USBWRAP_DEFAULT_TIMEOUT)
177 if( libusb_open(m_id, &m_handle) < 0 )
178 throw UsbError("open failed");
181 ~Device()
183 ClearIO(); // remove all pending IO before close
184 libusb_close(m_handle);
187 /////////////////////////////
188 // Data access
190 libusb_device_id_t GetID() const { return m_id; }
191 libusb_dev_handle_t * GetHandle() const { return m_handle; }
192 int GetLastError() const { return m_lasterror; }
195 /////////////////////////////
196 // Device manipulation
198 bool SetConfiguration(unsigned char cfg);
199 bool Reset();
202 /////////////////////////////
203 // IO functions
205 // perform async io and track the handles inside Device
206 void TrackBulkRead(int ep, Data &data);
207 void TrackBulkWrite(int ep, const Data &data);
208 void TrackInterruptRead(int ep, Data &data);
209 void TrackInterruptWrite(int ep, const Data &data);
210 IO PollCompletions(); //< extracts from tracking list!
211 void ClearIO() { m_ios.clear(); }
212 void ClearIO(int index);
214 // perform async io and don't track handles in Device, but
215 // return the IO handle immediately for the caller to deal with
216 // It is safe to use PollCompletions() along with these calls,
217 // keep in mind that PollCompletions() will return IO's for handles
218 // that it doesn't track, thereby duplicating IO's that you
219 // get from these async functions. The IO destructor will properly
220 // handle multiple cleanups, but if one IO is destroyed, the other
221 // becomes invalid on the low level, but the object doesn't know it.
223 // Best to use one or the other IO style. Remember you can IO.Wait()
224 // to block if needed.
226 IO ABulkRead(int ep, Data &data);
227 IO ABulkWrite(int ep, const Data &data);
228 IO ABulkWrite(int ep, const void *data, size_t size);
229 IO AInterruptRead(int ep, Data &data);
230 IO AInterruptWrite(int ep, const Data &data);
232 // tracking list access
233 int GetIOCount() const { return m_ios.size(); }
234 CIO GetIO(int index) const { return CIO(m_ios[index]); }
237 class Interface
239 Device &m_dev;
240 int m_iface;
241 public:
242 Interface(Device &dev, int iface)
243 : m_dev(dev), m_iface(iface)
245 if( libusb_claim_interface(dev.GetHandle(), iface) < 0 )
246 throw UsbError("claim interface failed");
249 ~Interface()
251 libusb_release_interface(m_dev.GetHandle(), m_iface);
255 } // namespace Usb
257 #endif