053c30c127f33e17ab6d3c3abc390b70059c5f43
[debian/gnuradio] / vrt / lib / socket_rx_buffer.h
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2008,2009 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 #ifndef INCLUDED_VRT_SOCKET_RX_BUFFER_H
22 #define INCLUDED_VRT_SOCKET_RX_BUFFER_H
23
24 #include <boost/utility.hpp>
25 #include <vector>
26 #include <memory>
27 #include <stdint.h>
28
29 namespace vrt {
30
31   class data_handler;
32
33   /*!
34    * \brief high-performance interface to receive datagrams
35    *
36    * On many systems it should be possible to implement this on top of libpcap
37    *
38    * \internal
39    */
40   class socket_rx_buffer : boost::noncopyable 
41   {
42     
43     int           d_fd;                 // socket file descriptor
44     bool          d_using_tpring;       // using kernel mapped packet ring
45     size_t        d_buflen;             // length of our buffer
46     uint8_t      *d_buf;                // packet ring
47     unsigned int  d_frame_nr;           // max frames on ring
48     size_t        d_frame_size;         // frame storage size
49     unsigned int  d_head;               // pointer to next frame
50
51     std::vector<uint8_t *>  d_ring;     // pointers into buffer
52   
53     bool frame_available();
54
55     void inc_head()
56     {
57       if (d_head + 1 >= d_frame_nr)
58         d_head = 0;
59       else
60         d_head = d_head + 1;
61     }
62
63     bool open();
64     bool close();
65     bool try_packet_ring();
66
67   public:
68
69     enum result {
70       EB_OK,            //< everything's fine
71       EB_ERROR,         //< A non-recoverable error occurred
72       EB_WOULD_BLOCK,   //< A timeout of 0 was specified and nothing was ready
73       EB_TIMED_OUT,     //< The timeout expired before anything was ready
74     };
75
76     static const unsigned int MAX_PKTLEN;
77     static const unsigned int MIN_PKTLEN;
78
79     /*!
80      * \param socket_fd file descriptor that corresponds to a socket
81      * \param rx_bufsize is a hint as to the number of bytes of memory
82      * to allocate for received ethernet frames (0 -> reasonable default)
83      */
84     socket_rx_buffer(int socket_fd, size_t rx_bufsize = 0);
85     ~socket_rx_buffer();
86     
87     /*!
88      * \brief Call \p f for each frame in the receive buffer.
89      * \param f is the frame data handler
90      * \param timeout (in ms) controls behavior when there are no frames to read
91      *
92      * If \p timeout is 0, rx_frames will not wait for frames if none are 
93      * available, and f will not be invoked.  If \p timeout is -1 (the 
94      * default), rx_frames will block indefinitely until frames are 
95      * available.  If \p timeout is positive, it indicates the number of
96      * milliseconds to wait for a frame to become available.  Once the
97      * timeout has expired, rx_frames will return, f never having been 
98      * invoked.
99      *
100      * \p f will be called on each frame that is available.
101      * \p f returns a bit mask with one of the following set or cleared:
102      * 
103      * data_handler::DONE -  return from rx_frames now even though more frames
104      *                       might be available; otherwise continue if more 
105      *                       frames are ready.
106      *
107      * \returns EB_OK if at least one frame was received
108      * \returns EB_WOULD_BLOCK if \p timeout is 0 and the call would have blocked
109      * \returns EB_TIMED_OUT if timeout occurred
110      * \returns EB_ERROR if there was an unrecoverable error.
111      */
112     result rx_frames(data_handler *f, int timeout=-1);
113
114     /*
115      * \brief Returns maximum possible number of frames in buffer
116      */
117     unsigned int max_frames() const { return d_using_tpring ? d_frame_nr : 0; }
118   };
119
120 };  // namespace vrt
121
122 #endif /* INCLUDED_VRT_SOCKET_RX_BUFFER_H */