GNU Radio 3.4.2 C++ API
darwin_libusb.h
Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /*
00003  * Copyright 2006,2009 Free Software Foundation, Inc.
00004  * 
00005  * This file is part of GNU Radio.
00006  *
00007  * GNU Radio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 3, or (at your option)
00010  * any later version.
00011  * 
00012  * GNU Radio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with GNU Radio; see the file COPYING.  If not, write to
00019  * the Free Software Foundation, Inc., 51 Franklin Street,
00020  * Boston, MA 02110-1301, USA.
00021  */
00022 
00023 /*
00024  * The following code was taken from LIBUSB verion 0.1.10a,
00025  * and makes the fusb_darwin codes do-able in the current GR
00026  * programming framework.  Parts and pieces were taken from
00027  * usbi.h, darwin.c, and error.h .
00028  *
00029  * LIBUSB version 0.1.10a is covered by the LGPL, version 2;
00030  * These codes are used with permission from:
00031  *   (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com>
00032  *   (c) 2002-2005 Nathan Hjelm <hjelmn@users.sourceforge.net>
00033  * All rights reserved.
00034  */
00035 
00036 #ifndef __DARWIN_LIBUSB_H__
00037 #define __DARWIN_LIBUSB_H__
00038 
00039 #include <IOKit/IOCFBundle.h>
00040 #include <IOKit/IOCFPlugIn.h>
00041 #include <IOKit/usb/IOUSBLib.h>
00042 #include <IOKit/IOKitLib.h>
00043 
00044 extern "C" {
00045 
00046 static const char* darwin_error_strings[] = {
00047   "no error",
00048   "device not opened for exclusive access",
00049   "no connection to an IOService",
00050   "no asyc port has been opened for interface",
00051   "another process has device opened for exclusive access",
00052   "pipe is stalled",
00053   "could not establish a connection to Darin kernel",
00054   "invalid argument",
00055   "unknown error"
00056 };
00057 
00058 static const char *
00059 darwin_error_str (int result)
00060 {
00061   switch (result) {
00062   case kIOReturnSuccess:
00063     return (darwin_error_strings[0]);
00064   case kIOReturnNotOpen:
00065     return (darwin_error_strings[1]);
00066   case kIOReturnNoDevice:
00067     return (darwin_error_strings[2]);
00068   case kIOUSBNoAsyncPortErr:
00069     return (darwin_error_strings[3]);
00070   case kIOReturnExclusiveAccess:
00071     return (darwin_error_strings[4]);
00072   case kIOUSBPipeStalled:
00073     return (darwin_error_strings[5]);
00074   case kIOReturnError:
00075     return (darwin_error_strings[6]);
00076   case kIOReturnBadArgument:
00077     return (darwin_error_strings[7]);
00078   default:
00079     return (darwin_error_strings[8]);
00080   }
00081 }
00082 
00083 /* not a valid errorno outside darwin.c */
00084 #define LUSBDARWINSTALL (ELAST+1)
00085 
00086 static int
00087 darwin_to_errno (int result)
00088 {
00089   switch (result) {
00090   case kIOReturnSuccess:
00091     return 0;
00092   case kIOReturnNotOpen:
00093     return EBADF;
00094   case kIOReturnNoDevice:
00095   case kIOUSBNoAsyncPortErr:
00096     return ENXIO;
00097   case kIOReturnExclusiveAccess:
00098     return EBUSY;
00099   case kIOUSBPipeStalled:
00100     return LUSBDARWINSTALL;
00101   case kIOReturnBadArgument:
00102     return EINVAL;
00103   case kIOReturnError:
00104   default:
00105     return 1;
00106   }
00107 }
00108 
00109 typedef enum {
00110   USB_ERROR_TYPE_NONE = 0,
00111   USB_ERROR_TYPE_STRING,
00112   USB_ERROR_TYPE_ERRNO,
00113 } usb_error_type_t;
00114 
00115 extern char usb_error_str[1024];
00116 extern int usb_error_errno;
00117 extern usb_error_type_t usb_error_type;
00118 
00119 #define USB_ERROR(r, x)                          \
00120   do {                                           \
00121     usb_error_type = USB_ERROR_TYPE_ERRNO;       \
00122     usb_error_errno = x;                         \
00123     return (r);                                  \
00124   } while (0)
00125 
00126 #define USB_ERROR_STR(r, x, format, args...)                            \
00127   do {                                                                  \
00128     usb_error_type = USB_ERROR_TYPE_STRING;                             \
00129     snprintf (usb_error_str, sizeof (usb_error_str) - 1,                \
00130               format, ## args);                                         \
00131     if (usb_debug) {                                                    \
00132       std::cerr << "USB error: " << usb_error_str << std::cerr;         \
00133     }                                                                   \
00134     return (r);                                                         \
00135   } while (0)
00136 
00137 #define USB_ERROR_STR_ORIG(x, format, args...)                          \
00138   do {                                                                  \
00139     usb_error_type = USB_ERROR_TYPE_STRING;                             \
00140     snprintf (usb_error_str, sizeof (usb_error_str) - 1,                \
00141               format, ## args);                                         \
00142     if (usb_debug) {                                                    \
00143       std::cerr << "USB error: " << usb_error_str << std::endl;         \
00144     }                                                                   \
00145     return (x);                                                         \
00146   } while (0)
00147 
00148 #define USB_ERROR_STR_NO_RET(x, format, args...)                        \
00149   do {                                                                  \
00150     usb_error_type = USB_ERROR_TYPE_STRING;                             \
00151     snprintf (usb_error_str, sizeof (usb_error_str) - 1,                \
00152               format, ## args);                                         \
00153     if (usb_debug) {                                                    \
00154       std::cerr << "USB error: " << usb_error_str << std::endl;         \
00155     }                                                                   \
00156   } while (0)
00157 
00158 /*
00159  * simple function that figures out what pipeRef
00160  * is associated with an endpoint
00161  */
00162 static int ep_to_pipeRef (darwin_dev_handle *device, int ep)
00163 {
00164   io_return_t ret;
00165   UInt8 numep, direction, number;
00166   UInt8 dont_care1, dont_care3;
00167   UInt16 dont_care2;
00168   int i;
00169 
00170   if (usb_debug > 3) {
00171     std::cerr << "Converting ep address to pipeRef." << std::endl;
00172   }
00173 
00174   /* retrieve the total number of endpoints on this interface */
00175   ret = (*(device->interface))->GetNumEndpoints(device->interface, &numep);
00176   if ( ret ) {
00177     if ( usb_debug > 3 ) {
00178       std::cerr << "ep_to_pipeRef: interface is "
00179                 << device->interface << std::endl;
00180     }
00181     USB_ERROR_STR_ORIG ( -ret, "ep_to_pipeRef: can't get number of "
00182                          "endpoints for interface" );
00183   }
00184 
00185   /* iterate through the pipeRefs until we find the correct one */
00186   for (i = 1 ; i <= numep ; i++) {
00187     ret = (*(device->interface))->GetPipeProperties
00188       (device->interface, i, &direction, &number,
00189        &dont_care1, &dont_care2, &dont_care3);
00190 
00191     if (ret != kIOReturnSuccess) {
00192       std::cerr << "ep_to_pipeRef: an error occurred getting "
00193                 << "pipe information on pipe " << i << std::endl;
00194 
00195       USB_ERROR_STR_ORIG (-darwin_to_errno(ret),
00196                           "ep_to_pipeRef(GetPipeProperties): %s",
00197                           darwin_error_str(ret));
00198     }
00199 
00200     if (usb_debug > 3) {
00201       std::cerr << "ep_to_pipeRef: Pipe " << i << ": DIR: "
00202                 << direction << " number: " << number << std::endl;
00203     }
00204 
00205     /* calculate the endpoint of the pipe and check it versus
00206        the requested endpoint */
00207     if ( ((direction << 7 & USB_ENDPOINT_DIR_MASK) |
00208           (number & USB_ENDPOINT_ADDRESS_MASK)) == ep ) {
00209       if (usb_debug > 3) {
00210         std::cerr << "ep_to_pipeRef: pipeRef for ep address "
00211                   << ep << " found: " << i << std::endl;
00212       }
00213       return (i);
00214     }
00215   }
00216 
00217   if (usb_debug > 3) {
00218     std::cerr << "ep_to_pipeRef: No pipeRef found with endpoint address "
00219               << ep << std::endl;
00220   }
00221 
00222   /* none of the found pipes match the requested endpoint */
00223   return (-1);
00224 }
00225 
00226 }
00227 #endif /* __DARWIN_LIBUSB_H__ */