[contrib] Allow Network Protocol header to display in rom-o-matic
[gpxe.git] / src / include / gpxe / xfer.h
blobedd37034518ec3450068e555029483457e7f1377
1 #ifndef _GPXE_XFER_H
2 #define _GPXE_XFER_H
4 /** @file
6 * Data transfer interfaces
8 */
10 FILE_LICENCE ( GPL2_OR_LATER );
12 #include <stddef.h>
13 #include <stdarg.h>
14 #include <gpxe/interface.h>
15 #include <gpxe/iobuf.h>
17 struct xfer_interface;
18 struct xfer_metadata;
20 /** Data transfer interface operations */
21 struct xfer_interface_operations {
22 /** Close interface
24 * @v xfer Data transfer interface
25 * @v rc Reason for close
27 void ( * close ) ( struct xfer_interface *xfer, int rc );
28 /** Redirect to new location
30 * @v xfer Data transfer interface
31 * @v type New location type
32 * @v args Remaining arguments depend upon location type
33 * @ret rc Return status code
35 int ( * vredirect ) ( struct xfer_interface *xfer, int type,
36 va_list args );
37 /** Check flow control window
39 * @v xfer Data transfer interface
40 * @ret len Length of window
42 * Flow control is regarded as advisory but not mandatory.
43 * Users who have control over their own rate of data
44 * generation should perform a flow control check before
45 * generating new data. Users who have no control (such as
46 * NIC drivers or filter layers) are not obliged to check.
48 * Data transfer interfaces must be prepared to accept
49 * datagrams even if they are advertising a window of zero
50 * bytes.
52 size_t ( * window ) ( struct xfer_interface *xfer );
53 /** Allocate I/O buffer
55 * @v xfer Data transfer interface
56 * @v len I/O buffer payload length
57 * @ret iobuf I/O buffer
59 struct io_buffer * ( * alloc_iob ) ( struct xfer_interface *xfer,
60 size_t len );
61 /** Deliver datagram as I/O buffer with metadata
63 * @v xfer Data transfer interface
64 * @v iobuf Datagram I/O buffer
65 * @v meta Data transfer metadata
66 * @ret rc Return status code
68 * A data transfer interface that wishes to support only raw
69 * data delivery should set this method to
70 * xfer_deliver_as_raw().
72 int ( * deliver_iob ) ( struct xfer_interface *xfer,
73 struct io_buffer *iobuf,
74 struct xfer_metadata *meta );
75 /** Deliver datagram as raw data
77 * @v xfer Data transfer interface
78 * @v data Data buffer
79 * @v len Length of data buffer
80 * @ret rc Return status code
82 * A data transfer interface that wishes to support only I/O
83 * buffer delivery should set this method to
84 * xfer_deliver_as_iob().
86 int ( * deliver_raw ) ( struct xfer_interface *xfer,
87 const void *data, size_t len );
90 /** A data transfer interface */
91 struct xfer_interface {
92 /** Generic object communication interface */
93 struct interface intf;
94 /** Operations for received messages */
95 struct xfer_interface_operations *op;
98 /** Basis positions for seek() events */
99 enum seek_whence {
100 SEEK_CUR = 0,
101 SEEK_SET,
104 /** Data transfer metadata */
105 struct xfer_metadata {
106 /** Position of data within stream */
107 off_t offset;
108 /** Basis for data position
110 * Must be one of @c SEEK_CUR or @c SEEK_SET.
112 int whence;
113 /** Source socket address, or NULL */
114 struct sockaddr *src;
115 /** Destination socket address, or NULL */
116 struct sockaddr *dest;
117 /** Network device, or NULL */
118 struct net_device *netdev;
122 * Describe seek basis
124 * @v whence Basis for new position
126 static inline __attribute__ (( always_inline )) const char *
127 whence_text ( int whence ) {
128 switch ( whence ) {
129 case SEEK_CUR: return "CUR";
130 case SEEK_SET: return "SET";
131 default: return "INVALID";
135 extern struct xfer_interface null_xfer;
136 extern struct xfer_interface_operations null_xfer_ops;
138 extern void xfer_close ( struct xfer_interface *xfer, int rc );
139 extern int xfer_vredirect ( struct xfer_interface *xfer, int type,
140 va_list args );
141 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
142 extern size_t xfer_window ( struct xfer_interface *xfer );
143 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
144 size_t len );
145 extern int xfer_deliver_iob ( struct xfer_interface *xfer,
146 struct io_buffer *iobuf );
147 extern int xfer_deliver_iob_meta ( struct xfer_interface *xfer,
148 struct io_buffer *iobuf,
149 struct xfer_metadata *meta );
150 extern int xfer_deliver_raw ( struct xfer_interface *xfer,
151 const void *data, size_t len );
152 extern int xfer_vprintf ( struct xfer_interface *xfer,
153 const char *format, va_list args );
154 extern int __attribute__ (( format ( printf, 2, 3 ) ))
155 xfer_printf ( struct xfer_interface *xfer, const char *format, ... );
156 extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
158 extern void ignore_xfer_close ( struct xfer_interface *xfer, int rc );
159 extern int ignore_xfer_vredirect ( struct xfer_interface *xfer,
160 int type, va_list args );
161 extern size_t unlimited_xfer_window ( struct xfer_interface *xfer );
162 extern size_t no_xfer_window ( struct xfer_interface *xfer );
163 extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer,
164 size_t len );
165 extern int xfer_deliver_as_raw ( struct xfer_interface *xfer,
166 struct io_buffer *iobuf,
167 struct xfer_metadata *meta );
168 extern int xfer_deliver_as_iob ( struct xfer_interface *xfer,
169 const void *data, size_t len );
170 extern int ignore_xfer_deliver_raw ( struct xfer_interface *xfer,
171 const void *data __unused, size_t len );
174 * Initialise a data transfer interface
176 * @v xfer Data transfer interface
177 * @v op Data transfer interface operations
178 * @v refcnt Containing object reference counter, or NULL
180 static inline void xfer_init ( struct xfer_interface *xfer,
181 struct xfer_interface_operations *op,
182 struct refcnt *refcnt ) {
183 xfer->intf.dest = &null_xfer.intf;
184 xfer->intf.refcnt = refcnt;
185 xfer->op = op;
189 * Initialise a static data transfer interface
191 * @v operations Data transfer interface operations
193 #define XFER_INIT( operations ) { \
194 .intf = { \
195 .dest = &null_xfer.intf, \
196 .refcnt = NULL, \
197 }, \
198 .op = operations, \
202 * Get data transfer interface from generic object communication interface
204 * @v intf Generic object communication interface
205 * @ret xfer Data transfer interface
207 static inline __attribute__ (( always_inline )) struct xfer_interface *
208 intf_to_xfer ( struct interface *intf ) {
209 return container_of ( intf, struct xfer_interface, intf );
213 * Get reference to destination data transfer interface
215 * @v xfer Data transfer interface
216 * @ret dest Destination interface
218 static inline __attribute__ (( always_inline )) struct xfer_interface *
219 xfer_get_dest ( struct xfer_interface *xfer ) {
220 return intf_to_xfer ( intf_get ( xfer->intf.dest ) );
224 * Drop reference to data transfer interface
226 * @v xfer Data transfer interface
228 static inline __attribute__ (( always_inline )) void
229 xfer_put ( struct xfer_interface *xfer ) {
230 intf_put ( &xfer->intf );
234 * Plug a data transfer interface into a new destination interface
236 * @v xfer Data transfer interface
237 * @v dest New destination interface
239 static inline __attribute__ (( always_inline )) void
240 xfer_plug ( struct xfer_interface *xfer, struct xfer_interface *dest ) {
241 plug ( &xfer->intf, &dest->intf );
245 * Plug two data transfer interfaces together
247 * @v a Data transfer interface A
248 * @v b Data transfer interface B
250 static inline __attribute__ (( always_inline )) void
251 xfer_plug_plug ( struct xfer_interface *a, struct xfer_interface *b ) {
252 plug_plug ( &a->intf, &b->intf );
256 * Unplug a data transfer interface
258 * @v xfer Data transfer interface
260 static inline __attribute__ (( always_inline )) void
261 xfer_unplug ( struct xfer_interface *xfer ) {
262 plug ( &xfer->intf, &null_xfer.intf );
266 * Stop using a data transfer interface
268 * @v xfer Data transfer interface
270 * After calling this method, no further messages will be received via
271 * the interface.
273 static inline void xfer_nullify ( struct xfer_interface *xfer ) {
274 xfer->op = &null_xfer_ops;
277 #endif /* _GPXE_XFER_H */