GNU Radio 3.4.0 C++ API
fusb_linux.h
Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /*
00003  * Copyright 2003 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 // Fast USB interface
00024 
00025 #ifndef _FUSB_LINUX_H_
00026 #define _FUSB_LINUX_H_
00027 
00028 #include <fusb.h>
00029 #include <list>
00030 
00031 struct  usbdevfs_urb;
00032 class   fusb_ephandle_linux;
00033 
00034 /*!
00035  * \brief linux specific implementation of fusb_devhandle using usbdevice_fs
00036  */
00037 class fusb_devhandle_linux : public fusb_devhandle {
00038 private:
00039   std::list<usbdevfs_urb*>       d_pending_rqsts;
00040 
00041   void pending_add (usbdevfs_urb *urb);
00042   bool pending_remove (usbdevfs_urb *urb);
00043   usbdevfs_urb * pending_get ();
00044 
00045 
00046 public:
00047   // CREATORS
00048   fusb_devhandle_linux (usb_dev_handle *udh);
00049   virtual ~fusb_devhandle_linux ();
00050 
00051   // MANIPULATORS
00052   virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p,
00053                                         int block_size = 0, int nblocks = 0);
00054 
00055   // internal use only
00056   bool _submit_urb (usbdevfs_urb *urb);
00057   bool _cancel_urb (usbdevfs_urb *urb);
00058   void _cancel_pending_rqsts (fusb_ephandle_linux *eph);
00059   bool _reap (bool ok_to_block_p);
00060   void _wait_for_completion ();
00061 };
00062 
00063 /*!
00064  * \brief linux specific implementation of fusb_ephandle using usbdevice_fs
00065  */
00066 
00067 class fusb_ephandle_linux : public fusb_ephandle {
00068 private:
00069   fusb_devhandle_linux         *d_devhandle;
00070   std::list<usbdevfs_urb*>      d_free_list;
00071   std::list<usbdevfs_urb*>      d_completed_list;
00072   usbdevfs_urb                 *d_write_work_in_progress;
00073   unsigned char                *d_write_buffer;
00074   usbdevfs_urb                 *d_read_work_in_progress;
00075   unsigned char                *d_read_buffer;
00076   unsigned char                *d_read_buffer_end;
00077 
00078   usbdevfs_urb *get_write_work_in_progress ();
00079   void reap_complete_writes ();
00080   bool reload_read_buffer ();
00081   bool submit_urb (usbdevfs_urb *urb);
00082   
00083 public:
00084   fusb_ephandle_linux (fusb_devhandle_linux *dh, int endpoint, bool input_p,
00085                        int block_size = 0, int nblocks = 0);
00086   virtual ~fusb_ephandle_linux ();
00087 
00088   virtual bool start ();        //!< begin streaming i/o
00089   virtual bool stop ();         //!< stop streaming i/o
00090 
00091   /*!
00092    * \returns \p nbytes if write was successfully enqueued, else -1.
00093    * Will block if no free buffers available.
00094    */
00095   virtual int write (const void *buffer, int nbytes);
00096 
00097   /*!
00098    * \returns number of bytes read or -1 if error.
00099    * number of bytes read will be <= nbytes.
00100    * Will block if no input available.
00101    */
00102   virtual int read (void *buffer, int nbytes);
00103 
00104   /*
00105    * block until all outstanding writes have completed
00106    */
00107   virtual void wait_for_completion ();
00108 
00109   // internal use only
00110   void free_list_add (usbdevfs_urb *urb);
00111   void completed_list_add (usbdevfs_urb *urb);
00112   usbdevfs_urb *free_list_get ();               // pop and return head of list or 0
00113   usbdevfs_urb *completed_list_get ();          // pop and return head of list or 0
00114 };
00115 
00116 #endif /* _FUSB_LINUX_H_ */