Universal Software Radio Peripheral
|
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__ */