diff --git a/src/net/stream.c b/src/net/stream.c index 98716817..92e00d73 100644 --- a/src/net/stream.c +++ b/src/net/stream.c @@ -27,6 +27,200 @@ #include #include +/** + * Connection established + * + * @v conn Stream connection + */ +void stream_connected ( struct stream_connection *conn ) { + struct stream_application *app = conn->app; + + DBGC ( app, "Stream %p connected\n", app ); + + /* Check connection actually exists */ + if ( ! app ) { + DBGC ( conn, "Stream connection %p has no application\n", + conn ); + return; + } + + /* Hand off to application */ + app->op->connected ( app ); +} + +/** + * Connection closed + * + * @v conn Stream connection + * @v rc Error code, if any + */ +void stream_closed ( struct stream_connection *conn, int rc ) { + struct stream_application *app = conn->app; + + DBGC ( app, "Stream %p closed (%s)\n", app, strerror ( rc ) ); + + /* Check connection actually exists */ + if ( ! app ) { + DBGC ( conn, "Stream connection %p has no application\n", + conn ); + return; + } + + /* Hand off to application */ + app->op->closed ( app, rc ); +} + +/** + * Transmit data + * + * @v conn Stream connection + * @v data Temporary data buffer + * @v len Length of temporary data buffer + */ +void stream_senddata ( struct stream_connection *conn, + void *data, size_t len ) { + struct stream_application *app = conn->app; + + DBGC2 ( app, "Stream %p sending data\n", app ); + + /* Check connection actually exists */ + if ( ! app ) { + DBGC ( conn, "Stream connection %p has no application\n", + conn ); + return; + } + + /* Hand off to application */ + app->op->senddata ( app, data, len ); +} + +/** + * Transmitted data acknowledged + * + * @v conn Stream connection + * @v len Length of acknowledged data + * + * @c len must not exceed the outstanding amount of unacknowledged + * data. + */ +void stream_acked ( struct stream_connection *conn, size_t len ) { + struct stream_application *app = conn->app; + + DBGC2 ( app, "Stream %p had %zd bytes acknowledged\n", app, len ); + + /* Check connection actually exists */ + if ( ! app ) { + DBGC ( conn, "Stream connection %p has no application\n", + conn ); + return; + } + + /* Hand off to application */ + app->op->acked ( app, len ); +} + +/** + * Receive new data + * + * @v conn Stream connection + * @v data Data + * @v len Length of data + */ +void stream_newdata ( struct stream_connection *conn, + void *data, size_t len ) { + struct stream_application *app = conn->app; + + DBGC2 ( app, "Stream %p received %zd bytes\n", app, len ); + + /* Check connection actually exists */ + if ( ! app ) { + DBGC ( conn, "Stream connection %p has no application\n", + conn ); + return; + } + + /* Hand off to application */ + app->op->newdata ( app, data, len ); +} + +/** + * Bind to local address + * + * @v app Stream application + * @v local Local address + * @ret rc Return status code + */ +int stream_bind ( struct stream_application *app, struct sockaddr *local ) { + struct stream_connection *conn = app->conn; + int rc; + + DBGC2 ( app, "Stream %p binding\n", app ); + + /* Check connection actually exists */ + if ( ! conn ) { + DBGC ( app, "Stream %p has no connection\n", app ); + return -ENOTCONN; + } + + /* Hand off to connection */ + if ( ( rc = conn->op->bind ( conn, local ) ) != 0 ) { + DBGC ( app, "Stream %p failed to bind: %s\n", + app, strerror ( rc ) ); + return rc; + } + + return 0; +} + +/** + * Connect to remote address + * + * @v app Stream application + * @v peer Remote address + * @ret rc Return status code + */ +int stream_connect ( struct stream_application *app, struct sockaddr *peer ) { + struct stream_connection *conn = app->conn; + int rc; + + DBGC2 ( app, "Stream %p connecting\n", app ); + + /* Check connection actually exists */ + if ( ! conn ) { + DBGC ( app, "Stream %p has no connection\n", app ); + return -ENOTCONN; + } + + /* Hand off to connection */ + if ( ( rc = conn->op->connect ( conn, peer ) ) != 0 ) { + DBGC ( app, "Stream %p failed to connect: %s\n", + app, strerror ( rc ) ); + return rc; + } + + return 0; +} + +/** + * Close connection + * + * @v app Stream application + */ +void stream_close ( struct stream_application *app ) { + struct stream_connection *conn = app->conn; + + DBGC2 ( app, "Stream %p closing\n", app ); + + /* Check connection actually exists */ + if ( ! conn ) { + DBGC ( app, "Stream %p has no connection\n", app ); + return; + } + + /* Hand off to connection */ + conn->op->close ( conn ); +} + /** * Send data via connection * @@ -50,7 +244,7 @@ int stream_send ( struct stream_application *app, void *data, size_t len ) { return -ENOTCONN; } - /* Send data via connection */ + /* Hand off to connection */ if ( ( rc = conn->op->send ( conn, data, len ) ) != 0 ) { DBGC ( app, "Stream %p failed to send %zd bytes: %s\n", app, len, strerror ( rc ) ); @@ -59,3 +253,31 @@ int stream_send ( struct stream_application *app, void *data, size_t len ) { return 0; } + +/** + * Notify connection that data is available to send + * + * @v app Stream application + * @ret rc Return status code + */ +int stream_kick ( struct stream_application *app ) { + struct stream_connection *conn = app->conn; + int rc; + + DBGC2 ( app, "Stream %p kicking connection\n", app ); + + /* Check connection actually exists */ + if ( ! conn ) { + DBGC ( app, "Stream %p has no connection\n", app ); + return -ENOTCONN; + } + + /* Hand off to connection */ + if ( ( rc = conn->op->kick ( conn ) ) != 0 ) { + DBGC ( app, "Stream %p failed to kick connection: %s\n", + app, strerror ( rc ) ); + return rc; + } + + return 0; +}