darwin_libusb.h

Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /*
00003  * Copyright 2006 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 static char *
00046 darwin_error_str (int result)
00047 {
00048   switch (result) {
00049   case kIOReturnSuccess:
00050     return "no error";
00051   case kIOReturnNotOpen:
00052     return "device not opened for exclusive access";
00053   case kIOReturnNoDevice:
00054     return "no connection to an IOService";
00055   case kIOUSBNoAsyncPortErr:
00056     return "no asyc port has been opened for interface";
00057   case kIOReturnExclusiveAccess:
00058     return "another process has device opened for exclusive access";
00059   case kIOUSBPipeStalled:
00060     return "pipe is stalled";
00061   case kIOReturnError:
00062     return "could not establish a connection to Darin kernel";
00063   case kIOReturnBadArgument:
00064     return "invalid argument";
00065   default:
00066     return "unknown error";
00067   }
00068 }
00069 
00070 /* not a valid errorno outside darwin.c */
00071 #define LUSBDARWINSTALL (ELAST+1)
00072 
00073 static int
00074 darwin_to_errno (int result)
00075 {
00076   switch (result) {
00077   case kIOReturnSuccess:
00078     return 0;
00079   case kIOReturnNotOpen:
00080     return EBADF;
00081   case kIOReturnNoDevice:
00082   case kIOUSBNoAsyncPortErr:
00083     return ENXIO;
00084   case kIOReturnExclusiveAccess:
00085     return EBUSY;
00086   case kIOUSBPipeStalled:
00087     return LUSBDARWINSTALL;
00088   case kIOReturnBadArgument:
00089     return EINVAL;
00090   case kIOReturnError:
00091   default:
00092     return 1;
00093   }
00094 }
00095 
00096 typedef enum {
00097   USB_ERROR_TYPE_NONE = 0,
00098   USB_ERROR_TYPE_STRING,
00099   USB_ERROR_TYPE_ERRNO,
00100 } usb_error_type_t;
00101 
00102 extern char usb_error_str[1024];
00103 extern int usb_error_errno;
00104 extern usb_error_type_t usb_error_type;
00105 
00106 #define USB_ERROR(r, x)                         \
00107         do { \
00108           usb_error_type = USB_ERROR_TYPE_ERRNO; \
00109           usb_error_errno = x; \
00110           return r; \
00111         } while (0)
00112 
00113 #define USB_ERROR_STR(r, x, format, args...)    \
00114         do { \
00115           usb_error_type = USB_ERROR_TYPE_STRING; \
00116           snprintf(usb_error_str, sizeof(usb_error_str) - 1, format, ## args); \
00117           if (usb_debug) \
00118             fprintf(stderr, "USB error: %s\n", usb_error_str);  \
00119           return r; \
00120         } while (0)
00121 
00122 #define USB_ERROR_STR_ORIG(x, format, args...)  \
00123         do { \
00124           usb_error_type = USB_ERROR_TYPE_STRING; \
00125           snprintf(usb_error_str, sizeof(usb_error_str) - 1, format, ## args); \
00126           if (usb_debug) \
00127             fprintf(stderr, "USB error: %s\n", usb_error_str);  \
00128           return x; \
00129         } while (0)
00130 
00131 #define USB_ERROR_STR_NO_RET(x, format, args...)        \
00132         do { \
00133           usb_error_type = USB_ERROR_TYPE_STRING; \
00134           snprintf(usb_error_str, sizeof(usb_error_str) - 1, format, ## args); \
00135           if (usb_debug) \
00136             fprintf(stderr, "USB error: %s\n", usb_error_str);  \
00137         } while (0)
00138 
00139 /* simple function that figures out what pipeRef is associated with an endpoint */
00140 static int ep_to_pipeRef (darwin_dev_handle *device, int ep)
00141 {
00142   io_return_t ret;
00143   UInt8 numep, direction, number;
00144   UInt8 dont_care1, dont_care3;
00145   UInt16 dont_care2;
00146   int i;
00147 
00148   if (usb_debug > 3)
00149     fprintf(stderr, "Converting ep address to pipeRef.\n");
00150 
00151   /* retrieve the total number of endpoints on this interface */
00152   ret = (*(device->interface))->GetNumEndpoints(device->interface, &numep);
00153   if ( ret ) {
00154     if ( usb_debug > 3 )
00155       fprintf ( stderr, "ep_to_pipeRef: interface is %p\n", device->interface );
00156     USB_ERROR_STR_ORIG ( -ret, "ep_to_pipeRef: can't get number of endpoints for interface" );
00157   }
00158 
00159   /* iterate through the pipeRefs until we find the correct one */
00160   for (i = 1 ; i <= numep ; i++) {
00161     ret = (*(device->interface))->GetPipeProperties(device->interface, i, &direction, &number,
00162                                                     &dont_care1, &dont_care2, &dont_care3);
00163 
00164     if (ret != kIOReturnSuccess) {
00165       fprintf (stderr, "ep_to_pipeRef: an error occurred getting pipe information on pipe %d\n",
00166                i );
00167       USB_ERROR_STR_ORIG (-darwin_to_errno(ret), "ep_to_pipeRef(GetPipeProperties): %s", darwin_error_str(ret));
00168     }
00169 
00170     if (usb_debug > 3)
00171       fprintf (stderr, "ep_to_pipeRef: Pipe %i: DIR: %i number: %i\n", i, direction, number);
00172 
00173     /* calculate the endpoint of the pipe and check it versus the requested endpoint */
00174     if ( ((direction << 7 & USB_ENDPOINT_DIR_MASK) | (number & USB_ENDPOINT_ADDRESS_MASK)) == ep ) {
00175       if (usb_debug > 3)
00176         fprintf(stderr, "ep_to_pipeRef: pipeRef for ep address 0x%02x found: 0x%02x\n", ep, i);
00177 
00178       return i;
00179     }
00180   }
00181 
00182   if (usb_debug > 3)
00183     fprintf(stderr, "ep_to_pipeRef: No pipeRef found with endpoint address 0x%02x.\n", ep);
00184   
00185   /* none of the found pipes match the requested endpoint */
00186   return -1;
00187 }
00188 
00189 }
00190 #endif /* __DARWIN_LIBUSB_H__ */

Generated on Thu Mar 5 09:01:06 2009 for GNU Radio 3.1.3 by  doxygen 1.5.8