2 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include <gpxe/stream.h>
32 * Associate application with connection
34 * @v app Stream application
35 * @v conn Stream connection
37 void stream_associate ( struct stream_application *app,
38 struct stream_connection *conn ) {
40 DBGC ( app, "Stream %p associating with connection %p\n", app, conn );
42 assert ( conn->app == NULL );
43 assert ( app->conn == NULL );
49 * Disassociate application from connection
51 * @v app Stream application
52 * @v conn Stream connection
54 static void stream_disassociate ( struct stream_application *app,
55 struct stream_connection *conn ) {
57 DBGC ( app, "Stream %p disassociating from connection %p\n",
60 assert ( conn->app == app );
61 assert ( app->conn == conn );
67 * Connection established
69 * @v conn Stream connection
71 void stream_connected ( struct stream_connection *conn ) {
72 struct stream_application *app = conn->app;
74 DBGC ( app, "Stream %p connected\n", app );
76 /* Check connection actually exists */
78 DBGC ( conn, "Stream connection %p has no application\n",
83 /* Hand off to application */
84 if ( app->op->connected )
85 app->op->connected ( app );
91 * @v conn Stream connection
92 * @v rc Error code, if any
94 void stream_closed ( struct stream_connection *conn, int rc ) {
95 struct stream_application *app = conn->app;
97 /* Check connection actually exists */
99 /* Not an error; don't display a debug message */
103 DBGC ( app, "Stream %p closed (%s)\n", app, strerror ( rc ) );
105 /* Disassociate application from connection */
106 stream_disassociate ( app, conn );
108 /* Hand off to application */
109 if ( app->op->closed )
110 app->op->closed ( app, rc );
116 * @v conn Stream connection
117 * @v data Temporary data buffer
118 * @v len Length of temporary data buffer
120 void stream_senddata ( struct stream_connection *conn,
121 void *data, size_t len ) {
122 struct stream_application *app = conn->app;
124 DBGC2 ( app, "Stream %p sending data\n", app );
126 /* Check connection actually exists */
128 DBGC ( conn, "Stream connection %p has no application\n",
133 /* Hand off to application */
134 if ( app->op->senddata )
135 app->op->senddata ( app, data, len );
139 * Transmitted data acknowledged
141 * @v conn Stream connection
142 * @v len Length of acknowledged data
144 * @c len must not exceed the outstanding amount of unacknowledged
147 void stream_acked ( struct stream_connection *conn, size_t len ) {
148 struct stream_application *app = conn->app;
150 DBGC2 ( app, "Stream %p had %zd bytes acknowledged\n", app, len );
152 /* Check connection actually exists */
154 DBGC ( conn, "Stream connection %p has no application\n",
159 /* Ignore zero-length blocks */
163 /* Hand off to application */
164 if ( app->op->acked )
165 app->op->acked ( app, len );
171 * @v conn Stream connection
173 * @v len Length of data
175 void stream_newdata ( struct stream_connection *conn,
176 void *data, size_t len ) {
177 struct stream_application *app = conn->app;
179 DBGC2 ( app, "Stream %p received %zd bytes\n", app, len );
181 /* Check connection actually exists */
183 DBGC ( conn, "Stream connection %p has no application\n",
188 /* Ignore zero-length blocks */
192 /* Hand off to application */
193 if ( app->op->newdata )
194 app->op->newdata ( app, data, len );
198 * Bind to local address
200 * @v app Stream application
201 * @v local Local address
202 * @ret rc Return status code
204 int stream_bind ( struct stream_application *app, struct sockaddr *local ) {
205 struct stream_connection *conn = app->conn;
208 DBGC2 ( app, "Stream %p binding\n", app );
210 /* Check connection actually exists */
212 DBGC ( app, "Stream %p has no connection\n", app );
216 /* Hand off to connection */
217 if ( ! conn->op->bind )
219 if ( ( rc = conn->op->bind ( conn, local ) ) != 0 ) {
220 DBGC ( app, "Stream %p failed to bind: %s\n",
221 app, strerror ( rc ) );
229 * Connect to remote address
231 * @v app Stream application
232 * @v peer Remote address
233 * @ret rc Return status code
235 int stream_connect ( struct stream_application *app, struct sockaddr *peer ) {
236 struct stream_connection *conn = app->conn;
239 DBGC2 ( app, "Stream %p connecting\n", app );
241 /* Check connection actually exists */
243 DBGC ( app, "Stream %p has no connection\n", app );
247 /* Hand off to connection */
248 if ( ! conn->op->connect )
250 if ( ( rc = conn->op->connect ( conn, peer ) ) != 0 ) {
251 DBGC ( app, "Stream %p failed to connect: %s\n",
252 app, strerror ( rc ) );
262 * @v app Stream application
264 void stream_close ( struct stream_application *app ) {
265 struct stream_connection *conn = app->conn;
267 DBGC2 ( app, "Stream %p closing\n", app );
269 /* Check connection actually exists */
271 /* Not an error; don't display a debug message */
275 /* Disassociate application from connection */
276 stream_disassociate ( app, conn );
278 /* Hand off to connection */
279 if ( ! conn->op->close )
281 conn->op->close ( conn );
285 * Send data via connection
287 * @v app Stream application
288 * @v data Data to send
289 * @v len Length of data
290 * @ret rc Return status code
292 * This method should be called only in the context of an
293 * application's senddata() method.
295 int stream_send ( struct stream_application *app,
296 const void *data, size_t len ) {
297 struct stream_connection *conn = app->conn;
300 DBGC2 ( app, "Stream %p sending %zd bytes\n", app, len );
302 /* Check connection actually exists */
304 DBGC ( app, "Stream %p has no connection\n", app );
308 /* Ignore zero-length blocks */
312 /* Hand off to connection */
313 if ( ! conn->op->send )
315 if ( ( rc = conn->op->send ( conn, data, len ) ) != 0 ) {
316 DBGC ( app, "Stream %p failed to send %zd bytes: %s\n",
317 app, len, strerror ( rc ) );
325 * Notify connection that data is available to send
327 * @v app Stream application
328 * @ret rc Return status code
330 int stream_kick ( struct stream_application *app ) {
331 struct stream_connection *conn = app->conn;
334 DBGC2 ( app, "Stream %p kicking connection\n", app );
336 /* Check connection actually exists */
338 DBGC ( app, "Stream %p has no connection\n", app );
342 /* Hand off to connection */
343 if ( ! conn->op->send )
345 if ( ( rc = conn->op->kick ( conn ) ) != 0 ) {
346 DBGC ( app, "Stream %p failed to kick connection: %s\n",
347 app, strerror ( rc ) );