xfer.h

Go to the documentation of this file.
00001 #ifndef _GPXE_XFER_H
00002 #define _GPXE_XFER_H
00003 
00004 /** @file
00005  *
00006  * Data transfer interfaces
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER );
00011 
00012 #include <stddef.h>
00013 #include <stdarg.h>
00014 #include <gpxe/interface.h>
00015 #include <gpxe/iobuf.h>
00016 
00017 struct xfer_interface;
00018 struct xfer_metadata;
00019 
00020 /** Data transfer interface operations */
00021 struct xfer_interface_operations {
00022         /** Close interface
00023          *
00024          * @v xfer              Data transfer interface
00025          * @v rc                Reason for close
00026          */
00027         void ( * close ) ( struct xfer_interface *xfer, int rc );
00028         /** Redirect to new location
00029          *
00030          * @v xfer              Data transfer interface
00031          * @v type              New location type
00032          * @v args              Remaining arguments depend upon location type
00033          * @ret rc              Return status code
00034          */
00035         int ( * vredirect ) ( struct xfer_interface *xfer, int type,
00036                               va_list args );
00037         /** Check flow control window
00038          *
00039          * @v xfer              Data transfer interface
00040          * @ret len             Length of window
00041          *
00042          * Flow control is regarded as advisory but not mandatory.
00043          * Users who have control over their own rate of data
00044          * generation should perform a flow control check before
00045          * generating new data.  Users who have no control (such as
00046          * NIC drivers or filter layers) are not obliged to check.
00047          *
00048          * Data transfer interfaces must be prepared to accept
00049          * datagrams even if they are advertising a window of zero
00050          * bytes.
00051          */
00052         size_t ( * window ) ( struct xfer_interface *xfer );
00053         /** Allocate I/O buffer
00054          *
00055          * @v xfer              Data transfer interface
00056          * @v len               I/O buffer payload length
00057          * @ret iobuf           I/O buffer
00058          */
00059         struct io_buffer * ( * alloc_iob ) ( struct xfer_interface *xfer,
00060                                              size_t len );
00061         /** Deliver datagram as I/O buffer with metadata
00062          *
00063          * @v xfer              Data transfer interface
00064          * @v iobuf             Datagram I/O buffer
00065          * @v meta              Data transfer metadata
00066          * @ret rc              Return status code
00067          *
00068          * A data transfer interface that wishes to support only raw
00069          * data delivery should set this method to
00070          * xfer_deliver_as_raw().
00071          */
00072         int ( * deliver_iob ) ( struct xfer_interface *xfer,
00073                                 struct io_buffer *iobuf,
00074                                 struct xfer_metadata *meta );
00075         /** Deliver datagram as raw data
00076          *
00077          * @v xfer              Data transfer interface
00078          * @v data              Data buffer
00079          * @v len               Length of data buffer
00080          * @ret rc              Return status code
00081          *
00082          * A data transfer interface that wishes to support only I/O
00083          * buffer delivery should set this method to
00084          * xfer_deliver_as_iob().
00085          */
00086         int ( * deliver_raw ) ( struct xfer_interface *xfer,
00087                                 const void *data, size_t len );
00088 };
00089 
00090 /** A data transfer interface */
00091 struct xfer_interface {
00092         /** Generic object communication interface */
00093         struct interface intf;
00094         /** Operations for received messages */
00095         struct xfer_interface_operations *op;
00096 };
00097 
00098 /** Basis positions for seek() events */
00099 enum seek_whence {
00100         SEEK_CUR = 0,
00101         SEEK_SET,
00102 };
00103 
00104 /** Data transfer metadata */
00105 struct xfer_metadata {
00106         /** Position of data within stream */
00107         off_t offset;
00108         /** Basis for data position
00109          *
00110          * Must be one of @c SEEK_CUR or @c SEEK_SET.
00111          */
00112         int whence;
00113         /** Source socket address, or NULL */
00114         struct sockaddr *src;
00115         /** Destination socket address, or NULL */
00116         struct sockaddr *dest;
00117         /** Network device, or NULL */
00118         struct net_device *netdev;
00119 };
00120 
00121 /**
00122  * Describe seek basis
00123  *
00124  * @v whence            Basis for new position
00125  */
00126 static inline __attribute__ (( always_inline )) const char *
00127 whence_text ( int whence ) {
00128         switch ( whence ) {
00129         case SEEK_CUR:  return "CUR";
00130         case SEEK_SET:  return "SET";
00131         default:        return "INVALID";
00132         }
00133 }
00134 
00135 extern struct xfer_interface null_xfer;
00136 extern struct xfer_interface_operations null_xfer_ops;
00137 
00138 extern void xfer_close ( struct xfer_interface *xfer, int rc );
00139 extern int xfer_vredirect ( struct xfer_interface *xfer, int type,
00140                             va_list args );
00141 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
00142 extern size_t xfer_window ( struct xfer_interface *xfer );
00143 extern struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer,
00144                                            size_t len );
00145 extern int xfer_deliver_iob ( struct xfer_interface *xfer,
00146                               struct io_buffer *iobuf );
00147 extern int xfer_deliver_iob_meta ( struct xfer_interface *xfer,
00148                                    struct io_buffer *iobuf,
00149                                    struct xfer_metadata *meta );
00150 extern int xfer_deliver_raw ( struct xfer_interface *xfer,
00151                               const void *data, size_t len );
00152 extern int xfer_vprintf ( struct xfer_interface *xfer,
00153                           const char *format, va_list args );
00154 extern int __attribute__ (( format ( printf, 2, 3 ) ))
00155 xfer_printf ( struct xfer_interface *xfer, const char *format, ... );
00156 extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
00157 
00158 extern void ignore_xfer_close ( struct xfer_interface *xfer, int rc );
00159 extern int ignore_xfer_vredirect ( struct xfer_interface *xfer,
00160                                    int type, va_list args );
00161 extern size_t unlimited_xfer_window ( struct xfer_interface *xfer );
00162 extern size_t no_xfer_window ( struct xfer_interface *xfer );
00163 extern struct io_buffer * default_xfer_alloc_iob ( struct xfer_interface *xfer,
00164                                                    size_t len );
00165 extern int xfer_deliver_as_raw ( struct xfer_interface *xfer,
00166                                  struct io_buffer *iobuf,
00167                                  struct xfer_metadata *meta );
00168 extern int xfer_deliver_as_iob ( struct xfer_interface *xfer,
00169                                  const void *data, size_t len );
00170 extern int ignore_xfer_deliver_raw ( struct xfer_interface *xfer,
00171                                      const void *data __unused, size_t len );
00172 
00173 /**
00174  * Initialise a data transfer interface
00175  *
00176  * @v xfer              Data transfer interface
00177  * @v op                Data transfer interface operations
00178  * @v refcnt            Containing object reference counter, or NULL
00179  */
00180 static inline void xfer_init ( struct xfer_interface *xfer,
00181                                struct xfer_interface_operations *op,
00182                                struct refcnt *refcnt ) {
00183         xfer->intf.dest = &null_xfer.intf;
00184         xfer->intf.refcnt = refcnt;
00185         xfer->op = op;
00186 }
00187 
00188 /**
00189  * Initialise a static data transfer interface
00190  *
00191  * @v operations                Data transfer interface operations
00192  */
00193 #define XFER_INIT( operations ) {                       \
00194                 .intf = {                               \
00195                         .dest = &null_xfer.intf,        \
00196                         .refcnt = NULL,                 \
00197                 },                                      \
00198                 .op = operations,                       \
00199         }
00200 
00201 /**
00202  * Get data transfer interface from generic object communication interface
00203  *
00204  * @v intf              Generic object communication interface
00205  * @ret xfer            Data transfer interface
00206  */
00207 static inline __attribute__ (( always_inline )) struct xfer_interface *
00208 intf_to_xfer ( struct interface *intf ) {
00209         return container_of ( intf, struct xfer_interface, intf );
00210 }
00211 
00212 /**
00213  * Get reference to destination data transfer interface
00214  *
00215  * @v xfer              Data transfer interface
00216  * @ret dest            Destination interface
00217  */
00218 static inline __attribute__ (( always_inline )) struct xfer_interface *
00219 xfer_get_dest ( struct xfer_interface *xfer ) {
00220         return intf_to_xfer ( intf_get ( xfer->intf.dest ) );
00221 }
00222 
00223 /**
00224  * Drop reference to data transfer interface
00225  *
00226  * @v xfer              Data transfer interface
00227  */
00228 static inline __attribute__ (( always_inline )) void
00229 xfer_put ( struct xfer_interface *xfer ) {
00230         intf_put ( &xfer->intf );
00231 }
00232 
00233 /**
00234  * Plug a data transfer interface into a new destination interface
00235  *
00236  * @v xfer              Data transfer interface
00237  * @v dest              New destination interface
00238  */
00239 static inline __attribute__ (( always_inline )) void
00240 xfer_plug ( struct xfer_interface *xfer, struct xfer_interface *dest ) {
00241         plug ( &xfer->intf, &dest->intf );
00242 }
00243 
00244 /**
00245  * Plug two data transfer interfaces together
00246  *
00247  * @v a                 Data transfer interface A
00248  * @v b                 Data transfer interface B
00249  */
00250 static inline __attribute__ (( always_inline )) void
00251 xfer_plug_plug ( struct xfer_interface *a, struct xfer_interface *b ) {
00252         plug_plug ( &a->intf, &b->intf );
00253 }
00254 
00255 /**
00256  * Unplug a data transfer interface
00257  *
00258  * @v xfer              Data transfer interface
00259  */
00260 static inline __attribute__ (( always_inline )) void
00261 xfer_unplug ( struct xfer_interface *xfer ) {
00262         plug ( &xfer->intf, &null_xfer.intf );
00263 }
00264 
00265 /**
00266  * Stop using a data transfer interface
00267  *
00268  * @v xfer              Data transfer interface
00269  *
00270  * After calling this method, no further messages will be received via
00271  * the interface.
00272  */
00273 static inline void xfer_nullify ( struct xfer_interface *xfer ) {
00274         xfer->op = &null_xfer_ops;
00275 };
00276 
00277 #endif /* _GPXE_XFER_H */

Generated on Tue Apr 6 20:01:09 2010 for gPXE by  doxygen 1.5.7.1