Home | History | Annotate | Download | only in gpxe
      1 #ifndef _GPXE_XFER_H
      2 #define _GPXE_XFER_H
      3 
      4 /** @file
      5  *
      6  * Data transfer interfaces
      7  *
      8  */
      9 
     10 FILE_LICENCE ( GPL2_OR_LATER );
     11 
     12 #include <stddef.h>
     13 #include <stdarg.h>
     14 #include <gpxe/interface.h>
     15 #include <gpxe/iobuf.h>
     16 
     17 struct xfer_interface;
     18 struct xfer_metadata;
     19 
     20 /** Data transfer interface operations */
     21 struct xfer_interface_operations {
     22 	/** Close interface
     23 	 *
     24 	 * @v xfer		Data transfer interface
     25 	 * @v rc		Reason for close
     26 	 */
     27 	void ( * close ) ( struct xfer_interface *xfer, int rc );
     28 	/** Redirect to new location
     29 	 *
     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
     34 	 */
     35 	int ( * vredirect ) ( struct xfer_interface *xfer, int type,
     36 			      va_list args );
     37 	/** Check flow control window
     38 	 *
     39 	 * @v xfer		Data transfer interface
     40 	 * @ret len		Length of window
     41 	 *
     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.
     47 	 *
     48 	 * Data transfer interfaces must be prepared to accept
     49 	 * datagrams even if they are advertising a window of zero
     50 	 * bytes.
     51 	 */
     52 	size_t ( * window ) ( struct xfer_interface *xfer );
     53 	/** Allocate I/O buffer
     54 	 *
     55 	 * @v xfer		Data transfer interface
     56 	 * @v len		I/O buffer payload length
     57 	 * @ret iobuf		I/O buffer
     58 	 */
     59 	struct io_buffer * ( * alloc_iob ) ( struct xfer_interface *xfer,
     60 					     size_t len );
     61 	/** Deliver datagram as I/O buffer with metadata
     62 	 *
     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
     67 	 *
     68 	 * A data transfer interface that wishes to support only raw
     69 	 * data delivery should set this method to
     70 	 * xfer_deliver_as_raw().
     71 	 */
     72 	int ( * deliver_iob ) ( struct xfer_interface *xfer,
     73 				struct io_buffer *iobuf,
     74 				struct xfer_metadata *meta );
     75 	/** Deliver datagram as raw data
     76 	 *
     77 	 * @v xfer		Data transfer interface
     78 	 * @v data		Data buffer
     79 	 * @v len		Length of data buffer
     80 	 * @ret rc		Return status code
     81 	 *
     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().
     85 	 */
     86 	int ( * deliver_raw ) ( struct xfer_interface *xfer,
     87 				const void *data, size_t len );
     88 };
     89 
     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;
     96 };
     97 
     98 /** Basis positions for seek() events */
     99 enum seek_whence {
    100 	SEEK_CUR = 0,
    101 	SEEK_SET,
    102 };
    103 
    104 /** Data transfer metadata */
    105 struct xfer_metadata {
    106 	/** Position of data within stream */
    107 	off_t offset;
    108 	/** Basis for data position
    109 	 *
    110 	 * Must be one of @c SEEK_CUR or @c SEEK_SET.
    111 	 */
    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;
    119 };
    120 
    121 /**
    122  * Describe seek basis
    123  *
    124  * @v whence		Basis for new position
    125  */
    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";
    132 	}
    133 }
    134 
    135 extern struct xfer_interface null_xfer;
    136 extern struct xfer_interface_operations null_xfer_ops;
    137 
    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 );
    157 
    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 );
    172 
    173 /**
    174  * Initialise a data transfer interface
    175  *
    176  * @v xfer		Data transfer interface
    177  * @v op		Data transfer interface operations
    178  * @v refcnt		Containing object reference counter, or NULL
    179  */
    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;
    186 }
    187 
    188 /**
    189  * Initialise a static data transfer interface
    190  *
    191  * @v operations		Data transfer interface operations
    192  */
    193 #define XFER_INIT( operations ) {			\
    194 		.intf = {				\
    195 			.dest = &null_xfer.intf,	\
    196 			.refcnt = NULL,			\
    197 		},					\
    198 		.op = operations,			\
    199 	}
    200 
    201 /**
    202  * Get data transfer interface from generic object communication interface
    203  *
    204  * @v intf		Generic object communication interface
    205  * @ret xfer		Data transfer interface
    206  */
    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 );
    210 }
    211 
    212 /**
    213  * Get reference to destination data transfer interface
    214  *
    215  * @v xfer		Data transfer interface
    216  * @ret dest		Destination interface
    217  */
    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 ) );
    221 }
    222 
    223 /**
    224  * Drop reference to data transfer interface
    225  *
    226  * @v xfer		Data transfer interface
    227  */
    228 static inline __attribute__ (( always_inline )) void
    229 xfer_put ( struct xfer_interface *xfer ) {
    230 	intf_put ( &xfer->intf );
    231 }
    232 
    233 /**
    234  * Plug a data transfer interface into a new destination interface
    235  *
    236  * @v xfer		Data transfer interface
    237  * @v dest		New destination interface
    238  */
    239 static inline __attribute__ (( always_inline )) void
    240 xfer_plug ( struct xfer_interface *xfer, struct xfer_interface *dest ) {
    241 	plug ( &xfer->intf, &dest->intf );
    242 }
    243 
    244 /**
    245  * Plug two data transfer interfaces together
    246  *
    247  * @v a			Data transfer interface A
    248  * @v b			Data transfer interface B
    249  */
    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 );
    253 }
    254 
    255 /**
    256  * Unplug a data transfer interface
    257  *
    258  * @v xfer		Data transfer interface
    259  */
    260 static inline __attribute__ (( always_inline )) void
    261 xfer_unplug ( struct xfer_interface *xfer ) {
    262 	plug ( &xfer->intf, &null_xfer.intf );
    263 }
    264 
    265 /**
    266  * Stop using a data transfer interface
    267  *
    268  * @v xfer		Data transfer interface
    269  *
    270  * After calling this method, no further messages will be received via
    271  * the interface.
    272  */
    273 static inline void xfer_nullify ( struct xfer_interface *xfer ) {
    274 	xfer->op = &null_xfer_ops;
    275 };
    276 
    277 #endif /* _GPXE_XFER_H */
    278