Preliminary support for opening data-transfer interfaces
[people/sha0/gpxe.git] / src / core / xfer.c
index d08b3b8..c399379 100644 (file)
@@ -16,6 +16,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <string.h>
 #include <errno.h>
 #include <gpxe/xfer.h>
 
  *
  */
 
+/**
+ * Send redirection event
+ *
+ * @v xfer             Data-transfer interface
+ * @v type             New location type
+ * @v args             Remaining arguments depend upon location type
+ * @ret rc             Return status code
+ */
+int vredirect ( struct xfer_interface *xfer, int type, va_list args ) {
+       struct xfer_interface *dest = xfer_dest ( xfer );
+
+       return dest->op->vredirect ( dest, type, args );
+}
+
+/**
+ * Send redirection event
+ *
+ * @v xfer             Data-transfer interface
+ * @v type             New location type
+ * @v ...              Remaining arguments depend upon location type
+ * @ret rc             Return status code
+ */
+int redirect ( struct xfer_interface *xfer, int type, ... ) {
+       va_list args;
+       int rc;
+
+       va_start ( args, type );
+       rc = vredirect ( xfer, type, args );
+       va_end ( args );
+       return rc;
+}
+
 /**
  * Deliver datagram
  *
 int deliver ( struct xfer_interface *xfer, struct io_buffer *iobuf ) {
        struct xfer_interface *dest = xfer_dest ( xfer );
 
-       return dest->op->deliver ( dest, xfer, iobuf );
+       return dest->op->deliver ( dest, iobuf );
+}
+
+/**
+ * Deliver datagram as raw data
+ *
+ * @v xfer             Data-transfer interface
+ * @v iobuf            Datagram I/O buffer
+ * @ret rc             Return status code
+ */
+int deliver_raw ( struct xfer_interface *xfer, const void *data, size_t len ) {
+       struct xfer_interface *dest = xfer_dest ( xfer );
+
+       return dest->op->deliver_raw ( dest, data, len );
 }
 
+/****************************************************************************
+ *
+ * Helper methods
+ *
+ * These functions are designed to be used as methods in the
+ * xfer_interface_operations table.
+ *
+ */
+
 /**
- * Null deliver datagram
+ * Deliver datagram as raw data
  *
  * @v xfer             Data-transfer interface
- * @v src              Source interface
  * @v iobuf            Datagram I/O buffer
  * @ret rc             Return status code
+ *
+ * This function is intended to be used as the deliver() method for
+ * data transfer interfaces that prefer to handle raw data.
  */
-static int null_deliver ( struct xfer_interface *xfer __unused,
-                         struct xfer_interface *src __unused,
-                         struct io_buffer *iobuf ) {
+int deliver_as_raw ( struct xfer_interface *xfer,
+                    struct io_buffer *iobuf ) {
+       int rc;
+
+       rc = xfer->op->deliver_raw ( xfer, iobuf->data, iob_len ( iobuf ) );
        free_iob ( iobuf );
+       return rc;
+}
+
+/**
+ * Deliver datagram as I/O buffer
+ *
+ * @v xfer             Data-transfer interface
+ * @v data             Data buffer
+ * @v len              Length of data buffer
+ * @ret rc             Return status code
+ *
+ * This function is intended to be used as the deliver_raw() method
+ * for data transfer interfaces that prefer to handle I/O buffers.
+ */
+int deliver_as_iobuf ( struct xfer_interface *xfer,
+                      const void *data, size_t len ) {
+       struct io_buffer *iobuf;
+
+       iobuf = alloc_iob ( len );
+       if ( ! iobuf )
+               return -ENOMEM;
+
+       memcpy ( iob_put ( iobuf, len ), data, len );
+       return xfer->op->deliver ( xfer, iobuf );
+}
+
+/****************************************************************************
+ *
+ * Null data transfer interface
+ *
+ */
+
+/**
+ * Null deliver datagram as raw data
+ *
+ * @v xfer             Data-transfer interface
+ * @v data             Data buffer
+ * @v len              Length of data buffer
+ * @ret rc             Return status code
+ */
+static int null_deliver_raw ( struct xfer_interface *xfer,
+                             const void *data __unused, size_t len ) {
+       DBGC ( xfer, "XFER %p %zd bytes delivered %s\n", xfer, len,
+              ( ( xfer == &null_xfer ) ?
+                "before connection" : "after termination" ) );
        return -EPIPE;
 }
 
 /** Null data transfer interface operations */
 struct xfer_interface_operations null_xfer_ops = {
-       .deliver = null_deliver,
+       .deliver        = deliver_as_raw,
+       .deliver_raw    = null_deliver_raw,
 };
 
 /**