68c1169e55f1fb9972284737ed0662afaf59c06a
[people/mcb30/gpxe.git] / src / include / gpxe / xfer.h
1 #ifndef _GPXE_XFER_H
2 #define _GPXE_XFER_H
3
4 /** @file
5  *
6  * Data transfer interfaces
7  *
8  */
9
10 #include <stddef.h>
11 #include <stdarg.h>
12 #include <gpxe/interface.h>
13 #include <gpxe/iobuf.h>
14
15 struct xfer_interface;
16 struct xfer_metadata;
17
18 /** Data transfer interface operations */
19 struct xfer_interface_operations {
20         /** Close interface
21          *
22          * @v xfer              Data transfer interface
23          * @v rc                Reason for close
24          */
25         void ( * close ) ( struct xfer_interface *xfer, int rc );
26         /** Redirect to new location
27          *
28          * @v xfer              Data transfer interface
29          * @v type              New location type
30          * @v args              Remaining arguments depend upon location type
31          * @ret rc              Return status code
32          */
33         int ( * vredirect ) ( struct xfer_interface *xfer, int type,
34                               va_list args );
35         /** Seek to position
36          *
37          * @v xfer              Data transfer interface
38          * @v offset            Offset to new position
39          * @v whence            Basis for new position
40          * @ret rc              Return status code
41          *
42          * @c whence must be one of @c SEEK_SET or @c SEEK_CUR.
43          */
44         int ( * seek ) ( struct xfer_interface *xfer, off_t offset,
45                          int whence );
46         /** Check flow control window
47          *
48          * @v xfer              Data transfer interface
49          * @ret len             Length of window
50          *
51          * Flow control is regarded as advisory but not mandatory.
52          * Users who have control over their own rate of data
53          * generation should perform a flow control check before
54          * generating new data.  Users who have no control (such as
55          * NIC drivers or filter layers) are not obliged to check.
56          *
57          * Data transfer interfaces must be prepared to accept
58          * datagrams even if they are advertising a window of zero
59          * bytes.
60          */
61         size_t ( * window ) ( struct xfer_interface *xfer );
62         /** Allocate I/O buffer
63          *
64          * @v xfer              Data transfer interface
65          * @v len               I/O buffer payload length
66          * @ret iobuf           I/O buffer
67          */
68         struct io_buffer * ( * alloc_iob ) ( struct xfer_interface *xfer,
69                                              size_t len );
70         /** Deliver datagram as I/O buffer with metadata
71          *
72          * @v xfer              Data transfer interface
73          * @v iobuf             Datagram I/O buffer
74          * @v meta              Data transfer metadata, or NULL
75          * @ret rc              Return status code
76          *
77          * A data transfer interface that wishes to support only raw
78          * data delivery should set this method to
79          * xfer_deliver_as_raw().
80          */
81         int ( * deliver_iob ) ( struct xfer_interface *xfer,
82                                 struct io_buffer *iobuf,
83                                 struct xfer_metadata *meta );
84         /** Deliver datagram as raw data
85          *
86          * @v xfer              Data transfer interface
87          * @v data              Data buffer
88          * @v len               Length of data buffer
89          * @ret rc              Return status code
90          *
91          * A data transfer interface that wishes to support only I/O
92          * buffer delivery should set this method to
93          * xfer_deliver_as_iob().
94          */
95         int ( * deliver_raw ) ( struct xfer_interface *xfer,
96                                 const void *data, size_t len );
97 };
98
99 /** A data transfer interface */
100 struct xfer_interface {
101         /** Generic object communication interface */
102         struct interface intf;
103         /** Operations for received messages */
104         struct xfer_interface_operations *op;
105 };
106
107 /** Data transfer metadata */
108 struct xfer_metadata {
109         /** Source socket address, or NULL */
110         struct sockaddr *src;
111         /** Destination socket address, or NULL */
112         struct sockaddr *dest;
113         /** Network device, or NULL */
114         struct net_device *netdev;
115 };
116
117 /** Basis positions for seek() events */
118 enum seek_whence {
119         SEEK_SET = 0,
120         SEEK_CUR,
121 };
122
123 /**
124  * Describe seek basis
125  *
126  * @v whence            Basis for new position
127  */
128 static inline __attribute__ (( always_inline )) const char *
129 whence_text ( int whence ) {
130         switch ( whence ) {
131         case SEEK_SET:  return "SET";
132         case SEEK_CUR:  return "CUR";
133         default:        return "INVALID";
134         }
135 }
136
137 extern struct xfer_interface null_xfer;
138 extern struct xfer_interface_operations null_xfer_ops;
139
140 extern void xfer_close ( struct xfer_interface *xfer, int rc );
141 extern int xfer_vredirect ( struct xfer_interface *xfer, int type,
142                             va_list args );
143 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
144 extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
145 extern size_t xfer_window ( struct xfer_interface *xfer );
146 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
147                                            size_t len );
148 extern int xfer_deliver_iob ( struct xfer_interface *xfer,
149                               struct io_buffer *iobuf );
150 extern int xfer_deliver_iob_meta ( struct xfer_interface *xfer,
151                                    struct io_buffer *iobuf,
152                                    struct xfer_metadata *meta );
153 extern int xfer_deliver_raw ( struct xfer_interface *xfer,
154                               const void *data, size_t len );
155 extern int xfer_vprintf ( struct xfer_interface *xfer,
156                           const char *format, va_list args );
157 extern int xfer_printf ( struct xfer_interface *xfer,
158                          const char *format, ... );
159
160 extern void ignore_xfer_close ( struct xfer_interface *xfer, int rc );
161 extern int ignore_xfer_vredirect ( struct xfer_interface *xfer,
162                                    int type, va_list args );
163 extern int ignore_xfer_seek ( struct xfer_interface *xfer, off_t offset,
164                               int whence );
165 extern size_t unlimited_xfer_window ( struct xfer_interface *xfer );
166 extern size_t no_xfer_window ( struct xfer_interface *xfer );
167 extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer,
168                                                    size_t len );
169 extern int xfer_deliver_as_raw ( struct xfer_interface *xfer,
170                                  struct io_buffer *iobuf,
171                                  struct xfer_metadata *meta );
172 extern int xfer_deliver_as_iob ( struct xfer_interface *xfer,
173                                  const void *data, size_t len );
174 extern int ignore_xfer_deliver_raw ( struct xfer_interface *xfer,
175                                      const void *data __unused, size_t len );
176
177 /**
178  * Initialise a data transfer interface
179  *
180  * @v xfer              Data transfer interface
181  * @v op                Data transfer interface operations
182  * @v refcnt            Containing object reference counter, or NULL
183  */
184 static inline void xfer_init ( struct xfer_interface *xfer,
185                                struct xfer_interface_operations *op,
186                                struct refcnt *refcnt ) {
187         xfer->intf.dest = &null_xfer.intf;
188         xfer->intf.refcnt = refcnt;
189         xfer->op = op;
190 }
191
192 /**
193  * Get data transfer interface from generic object communication interface
194  *
195  * @v intf              Generic object communication interface
196  * @ret xfer            Data transfer interface
197  */
198 static inline __attribute__ (( always_inline )) struct xfer_interface *
199 intf_to_xfer ( struct interface *intf ) {
200         return container_of ( intf, struct xfer_interface, intf );
201 }
202
203 /**
204  * Get reference to destination data transfer interface
205  *
206  * @v xfer              Data transfer interface
207  * @ret dest            Destination interface
208  */
209 static inline __attribute__ (( always_inline )) struct xfer_interface *
210 xfer_get_dest ( struct xfer_interface *xfer ) {
211         return intf_to_xfer ( intf_get ( xfer->intf.dest ) );
212 }
213
214 /**
215  * Drop reference to data transfer interface
216  *
217  * @v xfer              Data transfer interface
218  */
219 static inline __attribute__ (( always_inline )) void
220 xfer_put ( struct xfer_interface *xfer ) {
221         intf_put ( &xfer->intf );
222 }
223
224 /**
225  * Plug a data transfer interface into a new destination interface
226  *
227  * @v xfer              Data transfer interface
228  * @v dest              New destination interface
229  */
230 static inline __attribute__ (( always_inline )) void
231 xfer_plug ( struct xfer_interface *xfer, struct xfer_interface *dest ) {
232         plug ( &xfer->intf, &dest->intf );
233 }
234
235 /**
236  * Plug two data transfer interfaces together
237  *
238  * @v a                 Data transfer interface A
239  * @v b                 Data transfer interface B
240  */
241 static inline __attribute__ (( always_inline )) void
242 xfer_plug_plug ( struct xfer_interface *a, struct xfer_interface *b ) {
243         plug_plug ( &a->intf, &b->intf );
244 }
245
246 /**
247  * Unplug a data transfer interface
248  *
249  * @v xfer              Data transfer interface
250  */
251 static inline __attribute__ (( always_inline )) void
252 xfer_unplug ( struct xfer_interface *xfer ) {
253         plug ( &xfer->intf, &null_xfer.intf );
254 }
255
256 /**
257  * Stop using a data transfer interface
258  *
259  * @v xfer              Data transfer interface
260  *
261  * After calling this method, no further messages will be received via
262  * the interface.
263  */
264 static inline void xfer_nullify ( struct xfer_interface *xfer ) {
265         xfer->op = &null_xfer_ops;
266 };
267
268 #endif /* _GPXE_XFER_H */