First sketch of stream API
authorMichael Brown <mcb30@etherboot.org>
Wed, 31 Jan 2007 00:40:35 +0000 (00:40 +0000)
committerMichael Brown <mcb30@etherboot.org>
Wed, 31 Jan 2007 00:40:35 +0000 (00:40 +0000)
src/net/stream.c

index 9871681..92e00d7 100644 (file)
 #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
  *
@@ -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;
+}