GNU Radio 3.3.0 C++ API
|
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__ */