You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

xfer.h 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. #ifndef _GPXE_XFER_H
  2. #define _GPXE_XFER_H
  3. /** @file
  4. *
  5. * Data transfer interfaces
  6. *
  7. */
  8. #include <stddef.h>
  9. #include <stdarg.h>
  10. #include <gpxe/interface.h>
  11. #include <gpxe/iobuf.h>
  12. struct xfer_interface;
  13. struct xfer_metadata;
  14. /** Data transfer interface operations */
  15. struct xfer_interface_operations {
  16. /** Close interface
  17. *
  18. * @v xfer Data transfer interface
  19. * @v rc Reason for close
  20. */
  21. void ( * close ) ( struct xfer_interface *xfer, int rc );
  22. /** Redirect to new location
  23. *
  24. * @v xfer Data transfer interface
  25. * @v type New location type
  26. * @v args Remaining arguments depend upon location type
  27. * @ret rc Return status code
  28. */
  29. int ( * vredirect ) ( struct xfer_interface *xfer, int type,
  30. va_list args );
  31. /** Request data
  32. *
  33. * @v xfer Data transfer interface
  34. * @v offset Offset to new position
  35. * @v whence Basis for new position
  36. * @v len Length of requested data
  37. * @ret rc Return status code
  38. */
  39. int ( * request ) ( struct xfer_interface *xfer, off_t offset,
  40. int whence, size_t len );
  41. /** Seek to position
  42. *
  43. * @v xfer Data transfer interface
  44. * @v offset Offset to new position
  45. * @v whence Basis for new position
  46. * @ret rc Return status code
  47. *
  48. * @c whence must be one of @c SEEK_SET or @c SEEK_CUR. A
  49. * successful return indicates that the interface is ready to
  50. * immediately accept datagrams; return -EAGAIN if this is not
  51. * the case.
  52. */
  53. int ( * seek ) ( struct xfer_interface *xfer, off_t offset,
  54. int whence );
  55. /** Allocate I/O buffer
  56. *
  57. * @v xfer Data transfer interface
  58. * @v len I/O buffer payload length
  59. * @ret iobuf I/O buffer
  60. */
  61. struct io_buffer * ( * alloc_iob ) ( struct xfer_interface *xfer,
  62. size_t len );
  63. /** Deliver datagram as I/O buffer with metadata
  64. *
  65. * @v xfer Data transfer interface
  66. * @v iobuf Datagram I/O buffer
  67. * @v meta Data transfer metadata, or NULL
  68. * @ret rc Return status code
  69. *
  70. * A data transfer interface that wishes to support only raw
  71. * data delivery should set this method to
  72. * xfer_deliver_as_raw().
  73. *
  74. * Interfaces may not temporarily refuse to accept data by
  75. * returning -EAGAIN; such a response may be treated as a
  76. * fatal error.
  77. */
  78. int ( * deliver_iob ) ( struct xfer_interface *xfer,
  79. struct io_buffer *iobuf,
  80. struct xfer_metadata *meta );
  81. /** Deliver datagram as raw data
  82. *
  83. * @v xfer Data transfer interface
  84. * @v data Data buffer
  85. * @v len Length of data buffer
  86. * @ret rc Return status code
  87. *
  88. * A data transfer interface that wishes to support only I/O
  89. * buffer delivery should set this method to
  90. * xfer_deliver_as_iob().
  91. *
  92. * Interfaces may not temporarily refuse to accept data by
  93. * returning -EAGAIN; such a response may be treated as a
  94. * fatal error.
  95. */
  96. int ( * deliver_raw ) ( struct xfer_interface *xfer,
  97. const void *data, size_t len );
  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. /** Data transfer metadata */
  107. struct xfer_metadata {
  108. /** Source socket address, or NULL */
  109. struct sockaddr *src;
  110. /** Destination socket address, or NULL */
  111. struct sockaddr *dest;
  112. /** Network device, or NULL */
  113. struct net_device *netdev;
  114. };
  115. /** Basis positions for seek() events */
  116. enum seek_whence {
  117. SEEK_SET = 0,
  118. SEEK_CUR,
  119. };
  120. /**
  121. * Describe seek basis
  122. *
  123. * @v whence Basis for new position
  124. */
  125. static inline __attribute__ (( always_inline )) const char *
  126. whence_text ( int whence ) {
  127. switch ( whence ) {
  128. case SEEK_SET: return "SET";
  129. case SEEK_CUR: return "CUR";
  130. default: return "INVALID";
  131. }
  132. }
  133. extern struct xfer_interface null_xfer;
  134. extern struct xfer_interface_operations null_xfer_ops;
  135. extern void xfer_close ( struct xfer_interface *xfer, int rc );
  136. extern int xfer_vredirect ( struct xfer_interface *xfer, int type,
  137. va_list args );
  138. extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
  139. extern int xfer_request ( struct xfer_interface *xfer, off_t offset,
  140. int whence, size_t len );
  141. extern int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence );
  142. extern int xfer_ready ( 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 xfer_printf ( struct xfer_interface *xfer,
  155. const char *format, ... );
  156. extern void ignore_xfer_close ( struct xfer_interface *xfer, int rc );
  157. extern int ignore_xfer_vredirect ( struct xfer_interface *xfer,
  158. int type, va_list args );
  159. extern int ignore_xfer_request ( struct xfer_interface *xfer, off_t offset,
  160. int whence, size_t len );
  161. extern int ignore_xfer_seek ( struct xfer_interface *xfer, off_t offset,
  162. int whence );
  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. * Initialise a data transfer interface
  174. *
  175. * @v xfer Data transfer interface
  176. * @v op Data transfer interface operations
  177. * @v refcnt Containing object reference counter, or NULL
  178. */
  179. static inline void xfer_init ( struct xfer_interface *xfer,
  180. struct xfer_interface_operations *op,
  181. struct refcnt *refcnt ) {
  182. xfer->intf.dest = &null_xfer.intf;
  183. xfer->intf.refcnt = refcnt;
  184. xfer->op = op;
  185. }
  186. /**
  187. * Get data transfer interface from generic object communication interface
  188. *
  189. * @v intf Generic object communication interface
  190. * @ret xfer Data transfer interface
  191. */
  192. static inline __attribute__ (( always_inline )) struct xfer_interface *
  193. intf_to_xfer ( struct interface *intf ) {
  194. return container_of ( intf, struct xfer_interface, intf );
  195. }
  196. /**
  197. * Get reference to destination data transfer interface
  198. *
  199. * @v xfer Data transfer interface
  200. * @ret dest Destination interface
  201. */
  202. static inline __attribute__ (( always_inline )) struct xfer_interface *
  203. xfer_get_dest ( struct xfer_interface *xfer ) {
  204. return intf_to_xfer ( intf_get ( xfer->intf.dest ) );
  205. }
  206. /**
  207. * Drop reference to data transfer interface
  208. *
  209. * @v xfer Data transfer interface
  210. */
  211. static inline __attribute__ (( always_inline )) void
  212. xfer_put ( struct xfer_interface *xfer ) {
  213. intf_put ( &xfer->intf );
  214. }
  215. /**
  216. * Plug a data transfer interface into a new destination interface
  217. *
  218. * @v xfer Data transfer interface
  219. * @v dest New destination interface
  220. */
  221. static inline __attribute__ (( always_inline )) void
  222. xfer_plug ( struct xfer_interface *xfer, struct xfer_interface *dest ) {
  223. plug ( &xfer->intf, &dest->intf );
  224. }
  225. /**
  226. * Plug two data transfer interfaces together
  227. *
  228. * @v a Data transfer interface A
  229. * @v b Data transfer interface B
  230. */
  231. static inline __attribute__ (( always_inline )) void
  232. xfer_plug_plug ( struct xfer_interface *a, struct xfer_interface *b ) {
  233. plug_plug ( &a->intf, &b->intf );
  234. }
  235. /**
  236. * Unplug a data transfer interface
  237. *
  238. * @v xfer Data transfer interface
  239. */
  240. static inline __attribute__ (( always_inline )) void
  241. xfer_unplug ( struct xfer_interface *xfer ) {
  242. plug ( &xfer->intf, &null_xfer.intf );
  243. }
  244. /**
  245. * Stop using a data transfer interface
  246. *
  247. * @v xfer Data transfer interface
  248. *
  249. * After calling this method, no further messages will be received via
  250. * the interface.
  251. */
  252. static inline void xfer_nullify ( struct xfer_interface *xfer ) {
  253. xfer->op = &null_xfer_ops;
  254. };
  255. #endif /* _GPXE_XFER_H */