Added deliver-as-iobuf/deliver-as-raw concepts.
[people/holger/gpxe.git] / src / core / xfer.c
1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
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.
8  *
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.
13  *
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.
17  */
18
19 #include <string.h>
20 #include <errno.h>
21 #include <gpxe/xfer.h>
22
23 /** @file
24  *
25  * Data transfer interfaces
26  *
27  */
28
29 /**
30  * Deliver datagram
31  *
32  * @v xfer              Data-transfer interface
33  * @v iobuf             Datagram I/O buffer
34  * @ret rc              Return status code
35  */
36 int deliver ( struct xfer_interface *xfer, struct io_buffer *iobuf ) {
37         struct xfer_interface *dest = xfer_dest ( xfer );
38
39         return dest->op->deliver ( dest, xfer, iobuf );
40 }
41
42 /**
43  * Deliver datagram as raw data
44  *
45  * @v xfer              Data-transfer interface
46  * @v src               Source interface
47  * @v iobuf             Datagram I/O buffer
48  * @ret rc              Return status code
49  *
50  * This function is intended to be used as the deliver() method for
51  * data transfer interfaces that prefer to handle raw data.
52  */
53 int deliver_as_raw ( struct xfer_interface *xfer,
54                      struct xfer_interface *src,
55                      struct io_buffer *iobuf ) {
56         int rc;
57
58         rc = xfer->op->deliver_raw ( xfer, src, iobuf->data,
59                                      iob_len ( iobuf ) );
60         free_iob ( iobuf );
61         return rc;
62 }
63
64 /**
65  * Deliver datagram as I/O buffer
66  *
67  * @v xfer              Data-transfer interface
68  * @v src               Source interface
69  * @v data              Data buffer
70  * @v len               Length of data buffer
71  * @ret rc              Return status code
72  *
73  * This function is intended to be used as the deliver_raw() method
74  * for data transfer interfaces that prefer to handle I/O buffers.
75  */
76 int deliver_as_iobuf ( struct xfer_interface *xfer,
77                        struct xfer_interface *src,
78                        const void *data, size_t len ) {
79         struct io_buffer *iobuf;
80
81 #warning "Do we need interface-specific I/O buffer allocation?"
82         iobuf = alloc_iob ( len );
83         if ( ! iobuf )
84                 return -ENOMEM;
85
86         memcpy ( iob_put ( iobuf, len ), data, len );
87         return xfer->op->deliver ( xfer, src, iobuf );
88 }
89
90 /**
91  * Null deliver datagram as raw data
92  *
93  * @v xfer              Data-transfer interface
94  * @v src               Source interface
95  * @v data              Data buffer
96  * @v len               Length of data buffer
97  * @ret rc              Return status code
98  */
99 static int null_deliver_raw ( struct xfer_interface *xfer,
100                               struct xfer_interface *src,
101                               const void *data __unused, size_t len ) {
102         DBGC ( src, "XFER %p->%p %zd bytes delivered %s\n", src, xfer, len,
103                ( ( xfer == &null_xfer ) ?
104                  "before connection" : "after termination" ) );
105         return -EPIPE;
106 }
107
108 /** Null data transfer interface operations */
109 struct xfer_interface_operations null_xfer_ops = {
110         .deliver        = deliver_as_raw,
111         .deliver_raw    = null_deliver_raw,
112 };
113
114 /**
115  * Null data transfer interface
116  *
117  * This is the interface to which data transfer interfaces are
118  * connected when unplugged.  It will never generate messages, and
119  * will silently absorb all received messages.
120  */
121 struct xfer_interface null_xfer = {
122         .intf = {
123                 .dest = &null_xfer.intf,
124                 .refcnt = null_refcnt,
125         },
126         .op = &null_xfer_ops,
127 };