Preliminary support for opening data-transfer interfaces
[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  * Send redirection event
31  *
32  * @v xfer              Data-transfer interface
33  * @v type              New location type
34  * @v args              Remaining arguments depend upon location type
35  * @ret rc              Return status code
36  */
37 int vredirect ( struct xfer_interface *xfer, int type, va_list args ) {
38         struct xfer_interface *dest = xfer_dest ( xfer );
39
40         return dest->op->vredirect ( dest, type, args );
41 }
42
43 /**
44  * Send redirection event
45  *
46  * @v xfer              Data-transfer interface
47  * @v type              New location type
48  * @v ...               Remaining arguments depend upon location type
49  * @ret rc              Return status code
50  */
51 int redirect ( struct xfer_interface *xfer, int type, ... ) {
52         va_list args;
53         int rc;
54
55         va_start ( args, type );
56         rc = vredirect ( xfer, type, args );
57         va_end ( args );
58         return rc;
59 }
60
61 /**
62  * Deliver datagram
63  *
64  * @v xfer              Data-transfer interface
65  * @v iobuf             Datagram I/O buffer
66  * @ret rc              Return status code
67  */
68 int deliver ( struct xfer_interface *xfer, struct io_buffer *iobuf ) {
69         struct xfer_interface *dest = xfer_dest ( xfer );
70
71         return dest->op->deliver ( dest, iobuf );
72 }
73
74 /**
75  * Deliver datagram as raw data
76  *
77  * @v xfer              Data-transfer interface
78  * @v iobuf             Datagram I/O buffer
79  * @ret rc              Return status code
80  */
81 int deliver_raw ( struct xfer_interface *xfer, const void *data, size_t len ) {
82         struct xfer_interface *dest = xfer_dest ( xfer );
83
84         return dest->op->deliver_raw ( dest, data, len );
85 }
86
87 /****************************************************************************
88  *
89  * Helper methods
90  *
91  * These functions are designed to be used as methods in the
92  * xfer_interface_operations table.
93  *
94  */
95
96 /**
97  * Deliver datagram as raw data
98  *
99  * @v xfer              Data-transfer interface
100  * @v iobuf             Datagram I/O buffer
101  * @ret rc              Return status code
102  *
103  * This function is intended to be used as the deliver() method for
104  * data transfer interfaces that prefer to handle raw data.
105  */
106 int deliver_as_raw ( struct xfer_interface *xfer,
107                      struct io_buffer *iobuf ) {
108         int rc;
109
110         rc = xfer->op->deliver_raw ( xfer, iobuf->data, iob_len ( iobuf ) );
111         free_iob ( iobuf );
112         return rc;
113 }
114
115 /**
116  * Deliver datagram as I/O buffer
117  *
118  * @v xfer              Data-transfer interface
119  * @v data              Data buffer
120  * @v len               Length of data buffer
121  * @ret rc              Return status code
122  *
123  * This function is intended to be used as the deliver_raw() method
124  * for data transfer interfaces that prefer to handle I/O buffers.
125  */
126 int deliver_as_iobuf ( struct xfer_interface *xfer,
127                        const void *data, size_t len ) {
128         struct io_buffer *iobuf;
129
130         iobuf = alloc_iob ( len );
131         if ( ! iobuf )
132                 return -ENOMEM;
133
134         memcpy ( iob_put ( iobuf, len ), data, len );
135         return xfer->op->deliver ( xfer, iobuf );
136 }
137
138 /****************************************************************************
139  *
140  * Null data transfer interface
141  *
142  */
143
144 /**
145  * Null deliver datagram as raw data
146  *
147  * @v xfer              Data-transfer interface
148  * @v data              Data buffer
149  * @v len               Length of data buffer
150  * @ret rc              Return status code
151  */
152 static int null_deliver_raw ( struct xfer_interface *xfer,
153                               const void *data __unused, size_t len ) {
154         DBGC ( xfer, "XFER %p %zd bytes delivered %s\n", xfer, len,
155                ( ( xfer == &null_xfer ) ?
156                  "before connection" : "after termination" ) );
157         return -EPIPE;
158 }
159
160 /** Null data transfer interface operations */
161 struct xfer_interface_operations null_xfer_ops = {
162         .deliver        = deliver_as_raw,
163         .deliver_raw    = null_deliver_raw,
164 };
165
166 /**
167  * Null data transfer interface
168  *
169  * This is the interface to which data transfer interfaces are
170  * connected when unplugged.  It will never generate messages, and
171  * will silently absorb all received messages.
172  */
173 struct xfer_interface null_xfer = {
174         .intf = {
175                 .dest = &null_xfer.intf,
176                 .refcnt = null_refcnt,
177         },
178         .op = &null_xfer_ops,
179 };