# usbwrap.h

Go to the documentation of this file.

    00001 ///
    00002 /// \file       usbwrap.h
    00003 ///             USB API wrapper
    00004 ///
    00005
    00006 /*
    00007     Copyright (C) 2005-2011, Chris Frey
    00008
    00009     This program is free software; you can redistribute it and/or modify
    00010     it under the terms of the GNU General Public License as published by
    00011     the Free Software Foundation; either version 2 of the License, or
    00012     (at your option) any later version.
    00013
    00014     This program is distributed in the hope that it will be useful,
    00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00017
    00018     See the GNU General Public License in the COPYING file at the
    00019     root directory of this project for more details.
    00020 */
    00021
    00022
    00023 #ifndef __SB_USBWRAP_H__
    00024 #define __SB_USBWRAP_H__
    00025
    00026 #include "dll.h"
    00027
    00028 // On Windows systems, usb.h includes <windows.h> which defines min/max,
    00029 // which causes trouble for other headers
    00030 #include <usb.h>
    00031 #undef min
    00032 #undef max
    00033
    00034 #include <vector>
    00035 #include <map>
    00036 #include "error.h"
    00037
    00038 #define USBWRAP_DEFAULT_TIMEOUT 30000
    00039
    00040 namespace Barry { class Data; }
    00041
    00042 /// Namespace for the libusb-related wrapper classes.  This namespace
    00043 /// may change in the future.
    00044 namespace Usb {
    00045
    00046 /// \addtogroup exceptions
    00047 /// @{
    00048
    00049 /// Thrown on low level USB errors.
    00050 class BXEXPORT Error : public Barry::Error
    00051 {
    00052         int m_libusb_errcode;
    00053
    00054 public:
    00055         Error(const std::string &str);
    00056         Error(int libusb_errcode, const std::string &str);
    00057
    00058         // can return 0 in some case, if unknown error code
    00059         int libusb_errcode() const { return m_libusb_errcode; }
    00060 };
    00061
    00062 class BXEXPORT Timeout : public Error
    00063 {
    00064 public:
    00065         Timeout(const std::string &str) : Error(str) {}
    00066         Timeout(int libusb_errcode, const std::string &str)
    00067                 : Error(libusb_errcode, str) {}
    00068 };
    00069
    00070 /// @}
    00071
    00072 /// Typedefs used by the wrapper class, in the hope to make it
    00073 /// easier to switch from libusb stable to devel and back.
    00074 typedef struct usb_device*                      DeviceIDType;
    00075 typedef struct usb_dev_handle*                  DeviceHandleType;
    00076
    00077 class BXEXPORT Match
    00078 {
    00079 private:
    00080         struct usb_bus *m_busses;
    00081         struct usb_device *m_dev;
    00082         int m_vendor, m_product;
    00083         int m_lasterror;
    00084         const char *m_busname;
    00085         const char *m_devname;
    00086 protected:
    00087         static bool ToNum(const char *str, long &num);
    00088         static bool NameCompare(const char *n1, const char *n2);
    00089 public:
    00090         Match(int vendor, int product,
    00091                 const char *busname = 0, const char *devname = 0);
    00092         ~Match();
    00093
    00094         // searches for next match, and if found, fills devid with
    00095         // something you can pass on to DeviceDiscover, etc
    00096         // returns true if next is found, false if no more
    00097         bool next_device(Usb::DeviceIDType *devid);
    00098 };
    00099
    00100
    00101 class BXEXPORT Device
    00102 {
    00103 private:
    00104         Usb::DeviceIDType m_id;
    00105         Usb::DeviceHandleType m_handle;
    00106
    00107         int m_timeout;
    00108         int m_lasterror;
    00109
    00110 public:
    00111         Device(Usb::DeviceIDType id, int timeout = USBWRAP_DEFAULT_TIMEOUT);
    00112         ~Device();
    00113
    00114         /////////////////////////////
    00115         // Data access
    00116
    00117         Usb::DeviceIDType GetID() const { return m_id; }
    00118         Usb::DeviceHandleType GetHandle() const { return m_handle; }
    00119         int GetLastError() const { return m_lasterror; } //< not thread safe...
    00120                 //< use the error code stored in the exceptions to track
    00121                 //< errors in threaded usage
    00122         int GetDefaultTimeout() const { return m_timeout; }
    00123
    00124
    00125         /////////////////////////////
    00126         // Device manipulation
    00127
    00128         bool SetConfiguration(unsigned char cfg);
    00129         bool ClearHalt(int ep);
    00130         bool Reset();
    00131
    00132
    00133         /////////////////////////////
    00134         // IO functions
    00135
    00136         bool BulkRead(int ep, Barry::Data &data, int timeout = -1);
    00137         bool BulkWrite(int ep, const Barry::Data &data, int timeout = -1);
    00138         bool BulkWrite(int ep, const void *data, size_t size, int timeout = -1);
    00139         bool InterruptRead(int ep, Barry::Data &data, int timeout = -1);
    00140         bool InterruptWrite(int ep, const Barry::Data &data, int timeout = -1);
    00141
    00142         void BulkDrain(int ep, int timeout = 100);
    00143
    00144
    00145         /////////////////////////////
    00146         // Combo functions
    00147
    00148         bool GetConfiguration(unsigned char &cfg);
    00149         bool SetAltInterface(int iface);
    00150 };
    00151
    00152 class BXEXPORT Interface
    00153 {
    00154         Device &m_dev;
    00155         int m_iface;
    00156 public:
    00157         Interface(Device &dev, int iface);
    00158         ~Interface();
    00159 };
    00160
    00161
    00162
    00163
    00164 // Map of Endpoint numbers (not indexes) to endpoint descriptors
    00165 struct BXEXPORT EndpointPair
    00166 {
    00167         unsigned char read;
    00168         unsigned char write;
    00169         unsigned char type;
    00170
    00171         EndpointPair() : read(0), write(0), type(0xff) {}
    00172         bool IsTypeSet() const { return type != 0xff; }
    00173         bool IsComplete() const { return read && write && IsTypeSet(); }
    00174 };
    00175
    00176 class BXEXPORT EndpointDiscovery : public std::map<unsigned char, usb_endpoint_descriptor>
    00177 {
    00178         friend class InterfaceDiscovery;
    00179
    00180 public:
    00181         typedef std::map<unsigned char, usb_endpoint_descriptor>base_type;
    00182         typedef std::vector<EndpointPair>                       endpoint_array_type;
    00183
    00184 private:
    00185         bool m_valid;
    00186         endpoint_array_type m_endpoints;
    00187
    00188         BXLOCAL bool Discover(struct usb_interface_descriptor *interface, int epcount);
    00189
    00190 public:
    00191         EndpointDiscovery() : m_valid(false) {}
    00192
    00193         bool IsValid() const { return m_valid; }
    00194
    00195         const endpoint_array_type & GetEndpointPairs() const { return m_endpoints; }
    00196 };
    00197
    00198
    00199
    00200 // Map of Interface numbers (not indexes) to interface descriptors and endpoint map
    00201 struct BXEXPORT InterfaceDesc
    00202 {
    00203         usb_interface_descriptor desc;
    00204         EndpointDiscovery endpoints;
    00205 };
    00206
    00207 class BXEXPORT InterfaceDiscovery : public std::map<int, InterfaceDesc>
    00208 {
    00209 public:
    00210         typedef std::map<int, InterfaceDesc>                    base_type;
    00211
    00212 private:
    00213         bool m_valid;
    00214
    00215         BXLOCAL bool DiscoverInterface(struct usb_interface *interface);
    00216
    00217 public:
    00218         InterfaceDiscovery() : m_valid(false) {}
    00219
    00220         bool Discover(Usb::DeviceIDType devid, int cfgidx, int ifcount);
    00221         bool IsValid() const { return m_valid; }
    00222 };
    00223
    00224
    00225
    00226
    00227 // Map of Config numbers (not indexes) to config descriptors and interface map
    00228 struct BXEXPORT ConfigDesc
    00229 {
    00230         usb_config_descriptor desc;
    00231         InterfaceDiscovery interfaces;
    00232 };
    00233
    00234 class BXEXPORT ConfigDiscovery : public std::map<unsigned char, ConfigDesc>
    00235 {
    00236 public:
    00237         typedef std::map<unsigned char, ConfigDesc>             base_type;
    00238
    00239 private:
    00240         bool m_valid;
    00241
    00242 public:
    00243         ConfigDiscovery() : m_valid(false) {}
    00244
    00245         bool Discover(Usb::DeviceIDType devid, int cfgcount);
    00246         bool IsValid() const { return m_valid; }
    00247 };
    00248
    00249
    00250
    00251 // Discovers all configurations, interfaces, and endpoints for a given device
    00252 class BXEXPORT DeviceDiscovery
    00253 {
    00254         bool m_valid;
    00255
    00256 public:
    00257         usb_device_descriptor desc;
    00258         ConfigDiscovery configs;
    00259
    00260 public:
    00261         DeviceDiscovery(Usb::DeviceIDType devid);
    00262
    00263         bool Discover(Usb::DeviceIDType devid);
    00264         bool IsValid() const { return m_valid; }
    00265 };
    00266
    00267 } // namespace Usb
    00268
    00269 #endif
    00270