GNU Radio 3.3.0 C++ API
|
00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2006,2009,2010 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 #ifndef _FUSB_DARWIN_H_ 00024 #define _FUSB_DARWIN_H_ 00025 00026 #include <usb.h> 00027 #include "fusb.h" 00028 #include <IOKit/IOCFBundle.h> 00029 #include <IOKit/IOCFPlugIn.h> 00030 #include <IOKit/usb/IOUSBLib.h> 00031 #include <IOKit/IOKitLib.h> 00032 #include "circular_linked_list.h" 00033 #include "circular_buffer.h" 00034 00035 // for MacOS X 10.4.[0-3] 00036 #define usb_interface_t IOUSBInterfaceInterface220 00037 #define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220 00038 #define InterfaceVersion 220 00039 00040 // for MacOS X 10.3.[0-9] and 10.4.[0-3] 00041 #define usb_device_t IOUSBDeviceInterface197 00042 #define DeviceInterfaceID kIOUSBDeviceInterfaceID197 00043 #define DeviceVersion 197 00044 00045 extern "C" { 00046 typedef struct usb_dev_handle { 00047 int fd; 00048 00049 struct usb_bus *bus; 00050 struct usb_device *device; 00051 00052 int config; 00053 int interface; 00054 int altsetting; 00055 00056 /* Added by RMT so implementations can store other per-open-device data */ 00057 void *impl_info; 00058 } usb_dev_handle; 00059 00060 /* Darwin/OS X impl does not use fd field, instead it uses this */ 00061 typedef struct darwin_dev_handle { 00062 usb_device_t** device; 00063 usb_interface_t** interface; 00064 int open; 00065 } darwin_dev_handle; 00066 00067 typedef IOReturn io_return_t; 00068 typedef IOCFPlugInInterface *io_cf_plugin_ref_t; 00069 00070 static int ep_to_pipeRef (darwin_dev_handle* device, int ep); 00071 extern int usb_debug; 00072 } 00073 00074 class s_buffer 00075 { 00076 private: 00077 char* d_buffer; 00078 size_t d_n_used, d_n_alloc; 00079 00080 public: 00081 inline s_buffer (size_t n_alloc = 0) { 00082 d_n_used = 0; 00083 d_n_alloc = n_alloc; 00084 if (n_alloc) { 00085 d_buffer = (char*) new char [n_alloc]; 00086 } else { 00087 d_buffer = 0; 00088 } 00089 }; 00090 inline ~s_buffer () { 00091 if (d_n_alloc) { 00092 delete [] d_buffer; 00093 } 00094 }; 00095 inline size_t n_used () { return (d_n_used); }; 00096 inline void n_used (size_t bufLen) { 00097 d_n_used = (bufLen > d_n_alloc) ? d_n_alloc : bufLen; }; 00098 inline size_t n_alloc () { return (d_n_alloc); }; 00099 void buffer (char* l_buffer, size_t bufLen) { 00100 if (bufLen > d_n_alloc) { 00101 std::cerr << "s_buffer::set: Copying only allocated bytes." << std::endl; 00102 bufLen = d_n_alloc; 00103 } 00104 if (!l_buffer) { 00105 std::cerr << "s_buffer::set: NULL buffer." << std::endl; 00106 return; 00107 } 00108 bcopy (l_buffer, d_buffer, bufLen); 00109 d_n_used = bufLen; 00110 }; 00111 inline char* buffer () { return (d_buffer); }; 00112 inline void reset () { 00113 bzero (d_buffer, d_n_alloc); 00114 d_n_used = 0; 00115 }; 00116 }; 00117 00118 typedef s_buffer* s_buffer_ptr; 00119 typedef s_node<s_buffer_ptr>* s_node_ptr; 00120 typedef circular_linked_list<s_buffer_ptr>* s_queue_ptr; 00121 typedef s_both<s_buffer_ptr>* s_both_ptr; 00122 00123 /*! 00124 * \brief darwin implementation of fusb_devhandle 00125 * 00126 * This is currently identical to the generic implementation 00127 * and is intended as a starting point for whatever magic is 00128 * required to make usb fly. 00129 */ 00130 class fusb_devhandle_darwin : public fusb_devhandle 00131 { 00132 public: 00133 // CREATORS 00134 fusb_devhandle_darwin (usb_dev_handle* udh); 00135 virtual ~fusb_devhandle_darwin (); 00136 00137 // MANIPULATORS 00138 virtual fusb_ephandle* make_ephandle (int endpoint, bool input_p, 00139 int block_size = 0, int nblocks = 0); 00140 }; 00141 00142 /*! 00143 * \brief darwin implementation of fusb_ephandle 00144 * 00145 * This is currently identical to the generic implementation 00146 * and is intended as a starting point for whatever magic is 00147 * required to make usb fly. 00148 */ 00149 class fusb_ephandle_darwin : public fusb_ephandle 00150 { 00151 private: 00152 fusb_devhandle_darwin* d_devhandle; 00153 gruel::thread* d_runThread; 00154 gruel::mutex* d_runThreadRunning; 00155 00156 CFRunLoopRef d_CFRunLoopRef; 00157 00158 static void write_completed (void* ret_io_size, 00159 io_return_t result, 00160 void* io_size); 00161 static void read_completed (void* ret_io_size, 00162 io_return_t result, 00163 void* io_size); 00164 static void run_thread (void* arg); 00165 static void read_thread (void* arg); 00166 00167 void read_issue (s_both_ptr l_both); 00168 00169 public: 00170 // variables, for now 00171 UInt8 d_pipeRef, d_transferType; 00172 usb_interface_t** d_interfaceRef; 00173 usb_interface_t* d_interface; 00174 s_queue_ptr d_queue; 00175 circular_buffer<char>* d_buffer; 00176 size_t d_bufLenBytes; 00177 gruel::mutex* d_readRunning; 00178 gruel::mutex* d_runBlock_mutex; 00179 gruel::mutex* d_readBlock_mutex; 00180 gruel::condition_variable* d_runBlock; 00181 gruel::condition_variable* d_readBlock; 00182 00183 // CREATORS 00184 00185 fusb_ephandle_darwin (fusb_devhandle_darwin *dh, int endpoint, bool input_p, 00186 int block_size = 0, int nblocks = 0); 00187 virtual ~fusb_ephandle_darwin (); 00188 00189 // MANIPULATORS 00190 00191 virtual bool start (); //!< begin streaming i/o 00192 virtual bool stop (); //!< stop streaming i/o 00193 00194 /*! 00195 * \returns \p nbytes if write was successfully enqueued, else -1. 00196 * Will block if no free buffers available. 00197 */ 00198 virtual int write (const void* buffer, int nbytes); 00199 00200 /*! 00201 * \returns number of bytes read or -1 if error. 00202 * number of bytes read will be <= nbytes. 00203 * Will block if no input available. 00204 */ 00205 virtual int read (void* buffer, int nbytes); 00206 00207 /* 00208 * abort any pending IO transfers 00209 */ 00210 void abort (); 00211 00212 /* 00213 * block until all outstanding writes have completed 00214 */ 00215 virtual void wait_for_completion (); 00216 }; 00217 00218 #endif /* _FUSB_DARWIN_H_ */