6 * Data transfer interfaces
12 #include <gpxe/interface.h>
13 #include <gpxe/iobuf.h>
15 struct xfer_interface;
18 /** Data transfer interface operations */
19 struct xfer_interface_operations {
22 * @v xfer Data transfer interface
23 * @v rc Reason for close
25 void ( * close ) ( struct xfer_interface *xfer, int rc );
26 /** Redirect to new location
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
33 int ( * vredirect ) ( struct xfer_interface *xfer, int type,
37 * @v xfer Data transfer interface
38 * @v offset Offset to new position
39 * @v whence Basis for new position
40 * @v len Length of requested data
41 * @ret rc Return status code
43 int ( * request ) ( struct xfer_interface *xfer, off_t offset,
44 int whence, size_t len );
47 * @v xfer Data transfer interface
48 * @v offset Offset to new position
49 * @v whence Basis for new position
50 * @ret rc Return status code
52 * @c whence must be one of @c SEEK_SET or @c SEEK_CUR. A
53 * successful return indicates that the interface is ready to
54 * immediately accept datagrams; return -EAGAIN if this is not
57 int ( * seek ) ( struct xfer_interface *xfer, off_t offset,
59 /** Allocate I/O buffer
61 * @v xfer Data transfer interface
62 * @v len I/O buffer payload length
63 * @ret iobuf I/O buffer
65 struct io_buffer * ( * alloc_iob ) ( struct xfer_interface *xfer,
67 /** Deliver datagram as I/O buffer with metadata
69 * @v xfer Data transfer interface
70 * @v iobuf Datagram I/O buffer
71 * @v meta Data transfer metadata, or NULL
72 * @ret rc Return status code
74 * A data transfer interface that wishes to support only raw
75 * data delivery should set this method to
76 * xfer_deliver_as_raw().
78 * Interfaces may not temporarily refuse to accept data by
79 * returning -EAGAIN; such a response may be treated as a
82 int ( * deliver_iob ) ( struct xfer_interface *xfer,
83 struct io_buffer *iobuf,
84 struct xfer_metadata *meta );
85 /** Deliver datagram as raw data
87 * @v xfer Data transfer interface
89 * @v len Length of data buffer
90 * @ret rc Return status code
92 * A data transfer interface that wishes to support only I/O
93 * buffer delivery should set this method to
94 * xfer_deliver_as_iob().
96 * Interfaces may not temporarily refuse to accept data by
97 * returning -EAGAIN; such a response may be treated as a
100 int ( * deliver_raw ) ( struct xfer_interface *xfer,
101 const void *data, size_t len );
104 /** A data transfer interface */
105 struct xfer_interface {
106 /** Generic object communication interface */
107 struct interface intf;
108 /** Operations for received messages */
109 struct xfer_interface_operations *op;
112 /** Data transfer metadata */
113 struct xfer_metadata {
114 /** Source socket address, or NULL */
115 struct sockaddr *src;
116 /** Destination socket address, or NULL */
117 struct sockaddr *dest;
120 /** Basis positions for seek() events */
127 * Describe seek basis
129 * @v whence Basis for new position
131 static inline __attribute__ (( always_inline )) const char *
132 whence_text ( int whence ) {
134 case SEEK_SET: return "SET";
135 case SEEK_CUR: return "CUR";
136 default: return "INVALID";
140 extern struct xfer_interface null_xfer;
141 extern struct xfer_interface_operations null_xfer_ops;
143 extern void xfer_close ( struct xfer_interface *xfer, int rc );
144 extern int xfer_vredirect ( struct xfer_interface *xfer, int type,
146 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
147 extern int xfer_request ( struct xfer_interface *xfer, off_t offset,
148 int whence, size_t len );
149 extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
150 extern int xfer_ready ( struct xfer_interface *xfer );
151 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
153 extern int xfer_deliver_iob ( struct xfer_interface *xfer,
154 struct io_buffer *iobuf );
155 extern int xfer_deliver_iob_meta ( struct xfer_interface *xfer,
156 struct io_buffer *iobuf,
157 struct xfer_metadata *meta );
158 extern int xfer_deliver_raw ( struct xfer_interface *xfer,
159 const void *data, size_t len );
160 extern int xfer_vprintf ( struct xfer_interface *xfer,
161 const char *format, va_list args );
162 extern int xfer_printf ( struct xfer_interface *xfer,
163 const char *format, ... );
165 extern void ignore_xfer_close ( struct xfer_interface *xfer, int rc );
166 extern int ignore_xfer_vredirect ( struct xfer_interface *xfer,
167 int type, va_list args );
168 extern int ignore_xfer_request ( struct xfer_interface *xfer, off_t offset,
169 int whence, size_t len );
170 extern int ignore_xfer_seek ( struct xfer_interface *xfer, off_t offset,
172 extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer,
174 extern int xfer_deliver_as_raw ( struct xfer_interface *xfer,
175 struct io_buffer *iobuf,
176 struct xfer_metadata *meta );
177 extern int xfer_deliver_as_iob ( struct xfer_interface *xfer,
178 const void *data, size_t len );
179 extern int ignore_xfer_deliver_raw ( struct xfer_interface *xfer,
180 const void *data __unused, size_t len );
183 * Initialise a data transfer interface
185 * @v xfer Data transfer interface
186 * @v op Data transfer interface operations
187 * @v refcnt Containing object reference counter, or NULL
189 static inline void xfer_init ( struct xfer_interface *xfer,
190 struct xfer_interface_operations *op,
191 struct refcnt *refcnt ) {
192 xfer->intf.dest = &null_xfer.intf;
193 xfer->intf.refcnt = refcnt;
198 * Get data transfer interface from generic object communication interface
200 * @v intf Generic object communication interface
201 * @ret xfer Data transfer interface
203 static inline __attribute__ (( always_inline )) struct xfer_interface *
204 intf_to_xfer ( struct interface *intf ) {
205 return container_of ( intf, struct xfer_interface, intf );
209 * Get reference to destination data transfer interface
211 * @v xfer Data transfer interface
212 * @ret dest Destination interface
214 static inline __attribute__ (( always_inline )) struct xfer_interface *
215 xfer_get_dest ( struct xfer_interface *xfer ) {
216 return intf_to_xfer ( intf_get ( xfer->intf.dest ) );
220 * Drop reference to data transfer interface
222 * @v xfer Data transfer interface
224 static inline __attribute__ (( always_inline )) void
225 xfer_put ( struct xfer_interface *xfer ) {
226 intf_put ( &xfer->intf );
230 * Plug a data transfer interface into a new destination interface
232 * @v xfer Data transfer interface
233 * @v dest New destination interface
235 static inline __attribute__ (( always_inline )) void
236 xfer_plug ( struct xfer_interface *xfer, struct xfer_interface *dest ) {
237 plug ( &xfer->intf, &dest->intf );
241 * Plug two data transfer interfaces together
243 * @v a Data transfer interface A
244 * @v b Data transfer interface B
246 static inline __attribute__ (( always_inline )) void
247 xfer_plug_plug ( struct xfer_interface *a, struct xfer_interface *b ) {
248 plug_plug ( &a->intf, &b->intf );
252 * Unplug a data transfer interface
254 * @v xfer Data transfer interface
256 static inline __attribute__ (( always_inline )) void
257 xfer_unplug ( struct xfer_interface *xfer ) {
258 plug ( &xfer->intf, &null_xfer.intf );
262 * Stop using a data transfer interface
264 * @v xfer Data transfer interface
266 * After calling this method, no further messages will be received via
269 static inline void xfer_nullify ( struct xfer_interface *xfer ) {
270 xfer->op = &null_xfer_ops;
273 #endif /* _GPXE_XFER_H */