Add -mpreferred-stack-boundary=2 to i386 CFLAGS as it's almost always a win.
[people/indolent/gpxe.git/.git] / src / include / gpxe / stream.h
1 #ifndef _GPXE_STREAM_H
2 #define _GPXE_STREAM_H
3
4 /** @file
5  *
6  * Stream API
7  */
8
9 #include <stdint.h>
10 #include <gpxe/socket.h>
11
12 struct stream_application;
13 struct stream_connection;
14
15 /** Stream applicatin-layer operations */
16 struct stream_application_operations {
17         /**
18          * Connection established
19          *
20          * @v app               Stream application
21          */
22         void ( * connected ) ( struct stream_application *app );
23         /**
24          * Connection closed
25          *
26          * @v app               Stream application
27          * @v rc                Error code, if any
28          *
29          * This is called when the connection is closed for any
30          * reason, including timeouts or aborts.  The error code
31          * contains the negative error number, if the closure is due
32          * to an error, or zero for a normal close.
33          *
34          * When closed() is called, the application no longer has a
35          * valid stream connection.  Note that connected() may not
36          * have been called before closed(), if the close is due to an
37          * error during connection setup.
38          */
39         void ( * closed ) ( struct stream_application *app, int rc );
40         /**
41          * Transmit data
42          *
43          * @v app               Stream application
44          * @v data              Temporary data buffer
45          * @v len               Length of temporary data buffer
46          *
47          * The application should transmit whatever it currently wants
48          * to send using stream_send().  If retransmissions are
49          * required, senddata() will be called again and the
50          * application must regenerate the data.  The easiest way to
51          * implement this is to ensure that senddata() never changes
52          * the application's state.
53          *
54          * The application may use the temporary data buffer to
55          * construct the data to be sent.  Note that merely filling
56          * the buffer will do nothing; the application must call
57          * stream_send() in order to actually transmit the data.  Use
58          * of the buffer is not compulsory; the application may call
59          * stream_send() on any block of data.
60          */
61         void ( * senddata ) ( struct stream_application *app,
62                               void *data, size_t len );
63         /**
64          * Transmitted data acknowledged
65          *
66          * @v app               Stream application
67          * @v len               Length of acknowledged data
68          *
69          * @c len is guaranteed to not exceed the outstanding amount
70          * of unacknowledged data.
71          */
72         void ( * acked ) ( struct stream_application *app, size_t len );
73         /**
74          * Receive new data
75          *
76          * @v app               Stream application
77          * @v data              Data
78          * @v len               Length of data
79          */
80         void ( * newdata ) ( struct stream_application *app,
81                              void *data, size_t len );
82 };
83
84 /** Stream connection-layer operations */
85 struct stream_connection_operations {
86         /**
87          * Bind to local address
88          *
89          * @v conn              Stream connection
90          * @v local             Local address
91          * @ret rc              Return status code
92          */
93         int ( * bind ) ( struct stream_connection *conn,
94                          struct sockaddr *local );
95         /**
96          * Connect to remote address
97          *
98          * @v conn              Stream connection
99          * @v peer              Remote address
100          * @ret rc              Return status code
101          *
102          * This initiates the connection.  If the connection succeeds,
103          * the application's connected() method will be called.  If
104          * the connection fails (e.g. due to a timeout), the
105          * application's closed() method will be called with an
106          * appropriate error code.
107          */
108         int ( * connect ) ( struct stream_connection *conn,
109                             struct sockaddr *peer );
110         /**
111          * Close connection
112          *
113          * @v conn              Stream connection
114          */
115         void ( * close ) ( struct stream_connection *conn );
116         /**
117          * Send data via connection
118          *
119          * @v conn              Stream connection
120          * @v data              Data to send
121          * @v len               Length of data
122          * @ret rc              Return status code
123          *
124          * This method should be called only in the context of an
125          * application's senddata() method.
126          */
127         int ( * send ) ( struct stream_connection *conn,
128                          const void *data, size_t len );
129         /**
130          * Notify connection that data is available to send
131          *
132          * @v conn              Stream connection
133          * @ret rc              Return status code
134          *
135          * This will cause the connection to call the application's
136          * senddata() method.  It should be called when the
137          * application acquires new data to send as a result of
138          * something external to the data stream (e.g. when iSCSI is
139          * asked to issue a new command on an otherwise-idle
140          * connection).  Most applications will not need to call this
141          * method.
142          */
143         int ( * kick ) ( struct stream_connection *conn );
144 };
145
146 /** A stream application */
147 struct stream_application {
148         /** Stream connection, if any
149          *
150          * This will be NULL if the stream does not currently have a
151          * valid connection.
152          */
153         struct stream_connection *conn;
154         /** Stream application-layer operations */
155         struct stream_application_operations *op;
156 };
157
158 /** A stream connection */
159 struct stream_connection {
160         /** Stream application, if any
161          *
162          * This will be NULL if the stream does not currently have a
163          * valid application.
164          */
165         struct stream_application *app;
166         /** Stream connection-layer operations */
167         struct stream_connection_operations *op;        
168 };
169
170 extern void stream_associate ( struct stream_application *app,
171                                struct stream_connection *conn );
172
173 extern void stream_connected ( struct stream_connection *conn );
174 extern void stream_closed ( struct stream_connection *conn, int rc );
175 extern void stream_senddata ( struct stream_connection *conn,
176                               void *data, size_t len );
177 extern void stream_acked ( struct stream_connection *conn, size_t len );
178 extern void stream_newdata ( struct stream_connection *conn,
179                              void *data, size_t len );
180
181 extern int stream_bind ( struct stream_application *app,
182                          struct sockaddr *local );
183 extern int stream_connect ( struct stream_application *app,
184                             struct sockaddr *peer );
185 extern void stream_close ( struct stream_application *app );
186 extern int stream_send ( struct stream_application *app,
187                          const void *data, size_t len );
188 extern int stream_kick ( struct stream_application *app );
189
190 #endif /* _GPXE_STREAM_H */