usbwrap.cc

Go to the documentation of this file.
00001 ///
00002 /// \file       usbwrap.cc
00003 ///             USB API wrapper
00004 ///
00005 
00006 /*
00007     Copyright (C) 2005-2012, Chris Frey
00008     Portions Copyright (C) 2011, RealVNC Ltd.
00009 
00010     This program is free software; you can redistribute it and/or modify
00011     it under the terms of the GNU General Public License as published by
00012     the Free Software Foundation; either version 2 of the License, or
00013     (at your option) any later version.
00014 
00015     This program is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00018 
00019     See the GNU General Public License in the COPYING file at the
00020     root directory of this project for more details.
00021 */
00022 
00023 
00024 #include "usbwrap.h"
00025 #include "data.h"
00026 #include "error.h"
00027 #include "config.h"
00028 #include "debug.h"
00029 
00030 #include <iomanip>
00031 #include <sstream>
00032 #include <stdlib.h>
00033 #include <errno.h>
00034 #include <limits.h>
00035 
00036 #ifndef __DEBUG_MODE__
00037 #define __DEBUG_MODE__
00038 #endif
00039 #include "debug.h"
00040 
00041 // Pull in the correct Usb::LibraryInterface
00042 #if defined USE_LIBUSB_0_1
00043 #include "usbwrap_libusb.h"
00044 #elif defined USE_LIBUSB_1_0
00045 #include "usbwrap_libusb_1_0.h"
00046 #else
00047 #error No usb library interface selected.
00048 #endif
00049 
00050 
00051 namespace Usb {
00052 
00053 ///////////////////////////////////////////////////////////////////////////////
00054 // Usb::Error exception class
00055 
00056 static std::string GetErrorString(int libusb_errcode, const std::string &str)
00057 {
00058         std::ostringstream oss;
00059         oss << "(";
00060 
00061         if( libusb_errcode ) {
00062                 oss << std::dec << libusb_errcode << " ("
00063                     << LibraryInterface::TranslateErrcode(libusb_errcode)
00064                     << "), ";
00065         }
00066         oss << LibraryInterface::GetLastErrorString(libusb_errcode) << "): ";
00067         oss << str;
00068         return oss.str();
00069 }
00070 
00071 Error::Error(const std::string &str)
00072         : Barry::Error(str)
00073         , m_libusb_errcode(0)
00074 {
00075 }
00076 
00077 Error::Error(int libusb_errcode, const std::string &str)
00078         : Barry::Error(libusb_errcode == 0 ? str : GetErrorString(libusb_errcode, str))
00079         , m_libusb_errcode(libusb_errcode)
00080 {
00081 }
00082 
00083 int Error::system_errcode() const
00084 {
00085         return LibraryInterface::TranslateErrcode(m_libusb_errcode);
00086 }
00087 
00088 ///////////////////////////////////////////////////////////////////////////////
00089 // EndpointPair
00090 
00091 EndpointPair::EndpointPair()
00092         : read(0), write(0), type(EndpointDescriptor::InvalidType)
00093 {
00094 }
00095 
00096 bool EndpointPair::IsTypeSet() const
00097 {
00098         return type != EndpointDescriptor::InvalidType;
00099 }
00100 
00101 bool EndpointPair::IsComplete() const
00102 {
00103         return read && write && IsTypeSet();
00104 }
00105 
00106 bool EndpointPair::IsBulk() const
00107 {
00108         return type == EndpointDescriptor::BulkType;
00109 }
00110 
00111 
00112 ///////////////////////////////////////////////////////////////////////////////
00113 // EndpointPairings
00114 
00115 EndpointPairings::EndpointPairings(const std::vector<EndpointDescriptor*>& eps)
00116         : m_valid(false)
00117 {
00118         // parse the endpoint into read/write sets, if possible,
00119         // going in discovery order...
00120         // Assumptions:
00121         //      - endpoints of related utility will be grouped
00122         //      - endpoints with same type will be grouped
00123         //      - endpoints that do not meet the above assumptions
00124         //              do not belong in a pair
00125         EndpointPair pair;
00126 
00127         if( eps.size() == 0 ) {
00128                 dout("EndpointPairing:: empty interface pointer");
00129                 return;
00130         }
00131 
00132         std::vector<EndpointDescriptor*>::const_iterator iter = eps.begin();
00133         while( iter != eps.end() ) {
00134                 const EndpointDescriptor& desc = **iter;
00135                 if( desc.IsRead() ) {
00136                         // Read endpoint
00137                         pair.read = desc.GetAddress();
00138                         dout("        pair.read = 0x" << std::hex << (unsigned int)pair.read);
00139                         if( pair.IsTypeSet() && pair.type != desc.GetType() ) {
00140                                 // if type is already set, we must start over
00141                                 pair.write = 0;
00142                         }
00143                 } else {
00144                         // Write endpoint
00145                         pair.write = desc.GetAddress();
00146                         dout("        pair.write = 0x" << std::hex << (unsigned int)pair.write);
00147                         if( pair.IsTypeSet() && pair.type != desc.GetType() ) {
00148                                 // if type is already set, we must start over
00149                                 pair.read = 0;
00150                         }
00151                 }
00152                 pair.type = desc.GetType();
00153 
00154                 dout("        pair.type = 0x" << std::hex << (unsigned int)pair.type);
00155 
00156                 // if pair is complete, add to array
00157                 if( pair.IsComplete() ) {
00158                         push_back(pair);
00159 
00160                         dout("        pair added! ("
00161                              << "read: 0x" << std::hex << (unsigned int)pair.read << ","
00162                              << "write: 0x" << std::hex << (unsigned int)pair.write << ","
00163                              << "type: 0x" << std::hex << (unsigned int)pair.type << ")");
00164                         pair = EndpointPair();  // clear
00165                 }
00166                 ++iter;
00167         }
00168 
00169         m_valid = true;
00170 }
00171 
00172 EndpointPairings::~EndpointPairings()
00173 {
00174 }
00175 
00176 bool EndpointPairings::IsValid() const
00177 {
00178         return m_valid;
00179 }
00180 
00181 ///////////////////////////////////////////////////////////////////////////////
00182 // EndpointDescriptor
00183 
00184 bool EndpointDescriptor::IsRead() const
00185 {
00186         return m_read;
00187 }
00188 
00189 uint8_t EndpointDescriptor::GetAddress() const
00190 {
00191         return m_addr;
00192 }
00193 
00194 EndpointDescriptor::EpType EndpointDescriptor::GetType() const
00195 {
00196         return m_type;
00197 }
00198 
00199 ///////////////////////////////////////////////////////////////////////////////
00200 // Match
00201 
00202 Match::Match(DeviceList& devices,
00203              int vendor, int product,
00204              const char *busname, const char *devname)
00205         : m_list(devices.MatchDevices(vendor, product, busname, devname))
00206         , m_iter(m_list.begin())
00207 {
00208 
00209 }
00210 
00211 Match::~Match()
00212 {
00213 }
00214 
00215 bool Match::next_device(Usb::DeviceID& devid)
00216 {
00217         if( m_iter != m_list.end() ) {
00218                 devid = *m_iter;
00219                 ++m_iter;
00220                 return true;
00221         }
00222         return false;
00223 }
00224 
00225 } // namespace Usb
00226