3c46cdf2d2e46fd72771fa6e86eb9683fd5bb46a
[people/pcmattman/gpxe.git] / src / include / gpxe / xfer.h
1 #ifndef _GPXE_XFER_H
2 #define _GPXE_XFER_H
3
4 /** @file
5  *
6  * Data transfer interfaces
7  *
8  */
9
10 #include <stddef.h>
11 #include <stdarg.h>
12 #include <gpxe/interface.h>
13 #include <gpxe/iobuf.h>
14
15 struct xfer_interface;
16
17 /** Data transfer interface operations */
18 struct xfer_interface_operations {
19
20         /* Missing features:
21          *
22          * notification of non-close status - e.g. connected/opened, ...
23          *
24          * prompt for data delivery
25          *
26          * I/O buffer preparation
27          *
28          */
29
30         /** Start data transfer
31          *
32          * @v xfer              Data transfer interface
33          */
34         void ( * start ) ( struct xfer_interface *xfer );
35         /** Close interface
36          *
37          * @v xfer              Data transfer interface
38          * @v rc                Reason for close
39          */
40         void ( * close ) ( struct xfer_interface *xfer, int rc );
41         /** Redirect to new location
42          *
43          * @v xfer              Data transfer interface
44          * @v type              New location type
45          * @v args              Remaining arguments depend upon location type
46          * @ret rc              Return status code
47          */
48         int ( * vredirect ) ( struct xfer_interface *xfer, int type,
49                               va_list args );
50         /** Seek to position
51          *
52          * @v xfer              Data transfer interface
53          * @v pos               New position
54          * @ret rc              Return status code
55          */
56         int ( * seek ) ( struct xfer_interface *xfer, size_t pos );
57         /** Deliver datagram
58          *
59          * @v xfer              Data transfer interface
60          * @v iobuf             Datagram I/O buffer
61          * @ret rc              Return status code
62          *
63          * A data transfer interface that wishes to support only raw
64          * data delivery should set this method to
65          * xfer_deliver_as_raw().
66          */
67         int ( * deliver ) ( struct xfer_interface *xfer,
68                             struct io_buffer *iobuf );
69         /** Deliver datagram as raw data
70          *
71          * @v xfer              Data transfer interface
72          * @v data              Data buffer
73          * @v len               Length of data buffer
74          * @ret rc              Return status code
75          *
76          * A data transfer interface that wishes to support only I/O
77          * buffer delivery should set this method to
78          * xfer_deliver_as_iobuf().
79          */
80         int ( * deliver_raw ) ( struct xfer_interface *xfer,
81                                 const void *data, size_t len );
82 };
83
84 /** A data transfer interface */
85 struct xfer_interface {
86         /** Generic object communication interface */
87         struct interface intf;
88         /** Operations for received messages */
89         struct xfer_interface_operations *op;
90 };
91
92 extern struct xfer_interface null_xfer;
93 extern struct xfer_interface_operations null_xfer_ops;
94
95 extern void xfer_start ( struct xfer_interface *xfer );
96 extern void xfer_close ( struct xfer_interface *xfer, int rc );
97 extern int xfer_seek ( struct xfer_interface *xfer, size_t pos );
98 extern int xfer_vredirect ( struct xfer_interface *xfer, int type,
99                             va_list args );
100 extern int xfer_redirect ( struct xfer_interface *xfer, int type, ... );
101 extern int xfer_deliver ( struct xfer_interface *xfer,
102                           struct io_buffer *iobuf );
103 extern int xfer_deliver_raw ( struct xfer_interface *xfer,
104                               const void *data, size_t len );
105
106 extern void ignore_xfer_start ( struct xfer_interface *xfer );
107 extern void ignore_xfer_close ( struct xfer_interface *xfer, int rc );
108 extern int ignore_xfer_vredirect ( struct xfer_interface *xfer,
109                                    int type, va_list args );
110 extern int default_xfer_vredirect ( struct xfer_interface *xfer,
111                                     int type, va_list args );
112 extern int ignore_xfer_seek ( struct xfer_interface *xfer, size_t pos );
113 extern int xfer_deliver_as_raw ( struct xfer_interface *xfer,
114                                  struct io_buffer *iobuf );
115 extern int xfer_deliver_as_iobuf ( struct xfer_interface *xfer,
116                                    const void *data, size_t len );
117 extern int ignore_xfer_deliver_raw ( struct xfer_interface *xfer,
118                                      const void *data __unused, size_t len );
119
120 /**
121  * Initialise a data transfer interface
122  *
123  * @v xfer              Data transfer interface
124  * @v op                Data transfer interface operations
125  * @v refcnt            Containing object reference counter, or NULL
126  */
127 static inline void xfer_init ( struct xfer_interface *xfer,
128                                struct xfer_interface_operations *op,
129                                struct refcnt *refcnt ) {
130         xfer->intf.dest = &null_xfer.intf;
131         xfer->intf.refcnt = refcnt;
132         xfer->op = op;
133 }
134
135 /**
136  * Get data transfer interface from generic object communication interface
137  *
138  * @v intf              Generic object communication interface
139  * @ret xfer            Data transfer interface
140  */
141 static inline struct xfer_interface *
142 intf_to_xfer ( struct interface *intf ) {
143         return container_of ( intf, struct xfer_interface, intf );
144 }
145
146 /**
147  * Get destination data transfer interface
148  *
149  * @v xfer              Data transfer interface
150  * @ret dest            Destination interface
151  */
152 static inline struct xfer_interface *
153 xfer_dest ( struct xfer_interface *xfer ) {
154         return intf_to_xfer ( xfer->intf.dest );
155 }
156
157 /**
158  * Plug a data transfer interface into a new destination interface
159  *
160  * @v xfer              Data transfer interface
161  * @v dest              New destination interface
162  */
163 static inline void xfer_plug ( struct xfer_interface *xfer,
164                                struct xfer_interface *dest ) {
165         plug ( &xfer->intf, &dest->intf );
166 }
167
168 /**
169  * Plug two data transfer interfaces together
170  *
171  * @v a                 Data transfer interface A
172  * @v b                 Data transfer interface B
173  */
174 static inline void xfer_plug_plug ( struct xfer_interface *a,
175                                     struct xfer_interface *b ) {
176         plug_plug ( &a->intf, &b->intf );
177 }
178
179 /**
180  * Unplug a data transfer interface
181  *
182  * @v xfer              Data transfer interface
183  */
184 static inline void xfer_unplug ( struct xfer_interface *xfer ) {
185         plug ( &xfer->intf, &null_xfer.intf );
186 }
187
188 /**
189  * Stop using a data transfer interface
190  *
191  * @v xfer              Data transfer interface
192  *
193  * After calling this method, no further messages will be received via
194  * the interface.
195  */
196 static inline void xfer_nullify ( struct xfer_interface *xfer ) {
197         xfer->op = &null_xfer_ops;
198 };
199
200 #endif /* _GPXE_XFER_H */