#include <errno.h>
#include <gpxe/stream.h>
+/**
+ * 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
*
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 ) );
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;
+}