1 | /* |
2 | Copyright (c) 2012, Broadcom Europe Ltd |
3 | All rights reserved. |
4 | |
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the following conditions are met: |
7 | * Redistributions of source code must retain the above copyright |
8 | notice, this list of conditions and the following disclaimer. |
9 | * Redistributions in binary form must reproduce the above copyright |
10 | notice, this list of conditions and the following disclaimer in the |
11 | documentation and/or other materials provided with the distribution. |
12 | * Neither the name of the copyright holder nor the |
13 | names of its contributors may be used to endorse or promote products |
14 | derived from this software without specific prior written permission. |
15 | |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | #ifndef VC_NET_SOCKETS_H |
29 | #define VC_NET_SOCKETS_H |
30 | |
31 | /** \file net_sockets.h |
32 | * Abstraction layer for socket-style network communication, to enable porting |
33 | * between platforms. |
34 | * |
35 | * Does not support IPv6 multicast. |
36 | */ |
37 | |
38 | #include "containers/containers_types.h" |
39 | |
40 | #ifdef __cplusplus |
41 | extern "C" { |
42 | #endif |
43 | |
44 | /** Status codes that can occur in a socket instance. */ |
45 | typedef enum { |
46 | VC_CONTAINER_NET_SUCCESS = 0, /**< No error */ |
47 | VC_CONTAINER_NET_ERROR_GENERAL, /**< An unrecognised error has occurred */ |
48 | VC_CONTAINER_NET_ERROR_INVALID_SOCKET, /**< Invalid socket passed to function */ |
49 | VC_CONTAINER_NET_ERROR_NOT_ALLOWED, /**< The operation requested is not allowed */ |
50 | VC_CONTAINER_NET_ERROR_INVALID_PARAMETER, /**< An invalid parameter was passed in */ |
51 | VC_CONTAINER_NET_ERROR_NO_MEMORY, /**< Failure due to lack of memory */ |
52 | VC_CONTAINER_NET_ERROR_ACCESS_DENIED, /**< Permission denied */ |
53 | VC_CONTAINER_NET_ERROR_TOO_BIG, /**< Too many handles already open */ |
54 | VC_CONTAINER_NET_ERROR_WOULD_BLOCK, /**< Asynchronous operation would block */ |
55 | VC_CONTAINER_NET_ERROR_IN_PROGRESS, /**< An operation is already in progress on this socket */ |
56 | VC_CONTAINER_NET_ERROR_IN_USE, /**< The address/port is already in use */ |
57 | VC_CONTAINER_NET_ERROR_NETWORK, /**< Network is unavailable */ |
58 | VC_CONTAINER_NET_ERROR_CONNECTION_LOST, /**< The connection has been lost, closed by network, etc. */ |
59 | VC_CONTAINER_NET_ERROR_NOT_CONNECTED, /**< The socket is not connected */ |
60 | VC_CONTAINER_NET_ERROR_TIMED_OUT, /**< Operation timed out */ |
61 | VC_CONTAINER_NET_ERROR_CONNECTION_REFUSED, /**< Connection was refused by target */ |
62 | VC_CONTAINER_NET_ERROR_HOST_NOT_FOUND, /**< Target address could not be resolved */ |
63 | VC_CONTAINER_NET_ERROR_TRY_AGAIN, /**< A temporary failure occurred that may clear */ |
64 | } vc_container_net_status_t; |
65 | |
66 | /** Operations that can be applied to sockets */ |
67 | typedef enum { |
68 | /** Set the buffer size used on the socket |
69 | * arg1: uint32_t - New buffer size in bytes */ |
70 | VC_CONTAINER_NET_CONTROL_SET_READ_BUFFER_SIZE = 1, |
71 | /** Set the timeout to be used on read operations |
72 | * arg1: uint32_t - New timeout in milliseconds, or INFINITE_TIMEOUT_MS */ |
73 | VC_CONTAINER_NET_CONTROL_SET_READ_TIMEOUT_MS, |
74 | } vc_container_net_control_t; |
75 | |
76 | /** Container Input / Output Context. |
77 | * This is an opaque structure that defines the context for a socket instance. |
78 | * The details of the structure are contained within the platform implementation. */ |
79 | typedef struct vc_container_net_tag VC_CONTAINER_NET_T; |
80 | |
81 | /** \name Socket open flags |
82 | * The following flags can be used when opening a network socket. */ |
83 | /* @{ */ |
84 | typedef uint32_t vc_container_net_open_flags_t; |
85 | /** Connected stream socket, rather than connectionless datagram socket */ |
86 | #define VC_CONTAINER_NET_OPEN_FLAG_STREAM 1 |
87 | /** Force use of IPv4 addressing */ |
88 | #define VC_CONTAINER_NET_OPEN_FLAG_FORCE_IP4 2 |
89 | /** Force use of IPv6 addressing */ |
90 | #define VC_CONTAINER_NET_OPEN_FLAG_FORCE_IP6 6 |
91 | /** Use IPv4 broadcast address for datagram delivery */ |
92 | #define VC_CONTAINER_NET_OPEN_FLAG_IP4_BROADCAST 8 |
93 | /* @} */ |
94 | |
95 | /** Mask of bits used in forcing address type */ |
96 | #define VC_CONTAINER_NET_OPEN_FLAG_FORCE_MASK 6 |
97 | |
98 | /** Blocks until data is available, or an error occurs. |
99 | * Used with the VC_CONTAINER_NET_CONTROL_SET_READ_TIMEOUT_MS control operation. */ |
100 | #define INFINITE_TIMEOUT_MS 0xFFFFFFFFUL |
101 | |
102 | |
103 | /** Opens a network socket instance. |
104 | * The network address can be a host name, dotted IP4, hex IP6 address or NULL. Passing NULL |
105 | * signifies the socket is either to be used as a datagram receiver or a stream server, |
106 | * depending on the flags. |
107 | * \ref VC_CONTAINER_NET_OPEN_FLAG_STREAM will open the socket for connected streaming. The default |
108 | * is to use connectionless datagrams. |
109 | * \ref VC_CONTAINER_NET_OPEN_FLAG_FORCE_IP4 will force the use of IPv4 addressing or fail to open |
110 | * the socket. The default is to pick the first available. |
111 | * \ref VC_CONTAINER_NET_OPEN_FLAG_FORCE_IP6 will force the use of IPv6 addressing or fail to open |
112 | * the socket. The default is to pick the first available. |
113 | * \ref VC_CONTAINER_NET_OPEN_FLAG_IP4_BROADCAST will use IPv4 broadcast addressing for a datagram |
114 | * sender. Use with an IPv6 address, stream socket or datagram receiver will raise an error. |
115 | * If the p_status parameter is not NULL, the status code will be written to it to indicate the |
116 | * reason for failure, or VC_CONTAINER_NET_SUCCESS on success. |
117 | * Sockets shall be bound and connected as necessary. Stream server sockets shall further need |
118 | * to have vc_container_net_listen and vc_container_net_accept called on them before data can be transferred. |
119 | * |
120 | * \param address Network address or NULL. |
121 | * \param port Network port or well-known name. This is the local port for receivers/servers. |
122 | * \param flags Flags controlling socket type. |
123 | * \param p_status Optional pointer to variable to receive status of operation. |
124 | * \return The socket instance or NULL on error. */ |
125 | VC_CONTAINER_NET_T *vc_container_net_open( const char *address, const char *port, |
126 | vc_container_net_open_flags_t flags, vc_container_net_status_t *p_status ); |
127 | |
128 | /** Closes a network socket instance. |
129 | * The p_ctx pointer must not be used after it has been closed. |
130 | * |
131 | * \param p_ctx The socket instance to close. |
132 | * \return The status code for closing the socket. */ |
133 | vc_container_net_status_t vc_container_net_close( VC_CONTAINER_NET_T *p_ctx ); |
134 | |
135 | /** Query the latest status of the socket. |
136 | * |
137 | * \param p_ctx The socket instance. |
138 | * \return The status of the socket. */ |
139 | vc_container_net_status_t vc_container_net_status( VC_CONTAINER_NET_T *p_ctx ); |
140 | |
141 | /** Read data from the socket. |
142 | * The function will read up to the requested number of bytes into the buffer. |
143 | * If there is no data immediately available to read, the function will block |
144 | * until data arrives, an error occurs or the timeout is reached (if set). |
145 | * When the function returns zero, the socket may have been closed, an error |
146 | * may have occurred, a zero length datagram received, or the timeout reached. |
147 | * Check vc_container_net_status() to differentiate. |
148 | * Attempting to read on a datagram sender socket will trigger an error. |
149 | * |
150 | * \param p_ctx The socket instance. |
151 | * \param buffer The buffer into which bytes will be read. |
152 | * \param size The maximum number of bytes to read. |
153 | * \return The number of bytes actually read. */ |
154 | size_t vc_container_net_read( VC_CONTAINER_NET_T *p_ctx, void *buffer, size_t size ); |
155 | |
156 | /** Write data to the socket. |
157 | * If the socket cannot send the requested number of bytes in one go, the function |
158 | * will return a value smaller than size. |
159 | * Attempting to write on a datagram receiver socket will trigger an error. |
160 | * |
161 | * \param p_ctx The socket instance. |
162 | * \param buffer The buffer from which bytes will be written. |
163 | * \param size The maximum number of bytes to write. |
164 | * \return The number of bytes actually written. */ |
165 | size_t vc_container_net_write( VC_CONTAINER_NET_T *p_ctx, const void *buffer, size_t size ); |
166 | |
167 | /** Start a stream server socket listening for connections from clients. |
168 | * Attempting to use this on anything other than a stream server socket shall |
169 | * trigger an error. |
170 | * |
171 | * \param p_ctx The socket instance. |
172 | * \param maximum_connections The maximum number of queued connections to allow. |
173 | * \return The status of the socket. */ |
174 | vc_container_net_status_t vc_container_net_listen( VC_CONTAINER_NET_T *p_ctx, uint32_t maximum_connections ); |
175 | |
176 | /** Accept a client connection on a listening stream server socket. |
177 | * Attempting to use this on anything other than a listening stream server socket |
178 | * shall trigger an error. |
179 | * When a client connection is made, the new instance representing it is returned |
180 | * via pp_client_ctx. |
181 | * |
182 | * \param p_server ctx The server socket instance. |
183 | * \param pp_client_ctx The address where the pointer to the new client's socket |
184 | * instance is written. |
185 | * \return The status of the socket. */ |
186 | vc_container_net_status_t vc_container_net_accept( VC_CONTAINER_NET_T *p_server_ctx, VC_CONTAINER_NET_T **pp_client_ctx ); |
187 | |
188 | /** Non-blocking check for data being available to read. |
189 | * If an error occurs, the function will return false and the error can be |
190 | * obtained using socket_status(). |
191 | * |
192 | * \param p_ctx The socket instance. |
193 | * \return True if there is data available to read immediately. */ |
194 | bool vc_container_net_is_data_available( VC_CONTAINER_NET_T *p_ctx ); |
195 | |
196 | /** Returns the maximum size of a datagram in bytes, for sending or receiving. |
197 | * The limit for reading from or writing to stream sockets will generally be |
198 | * greater than this value, although the call can also be made on such sockets. |
199 | * |
200 | * \param p_ctx The socket instance. |
201 | * \return The maximum size of a datagram in bytes. */ |
202 | size_t vc_container_net_maximum_datagram_size( VC_CONTAINER_NET_T *p_ctx ); |
203 | |
204 | /** Get the DNS name or IP address of a stream server client, if connected. |
205 | * The length of the name will be limited by name_len, taking into account a |
206 | * terminating NUL character. |
207 | * Calling this function on a non-stream server instance, or one that is not |
208 | * connected to a client, will result in an error status. |
209 | * |
210 | * \param p_ctx The socket instance. |
211 | * \param name Pointer where the name should be written. |
212 | * \param name_len Maximum number of characters to write to name. |
213 | * \return The status of the socket. */ |
214 | vc_container_net_status_t vc_container_net_get_client_name( VC_CONTAINER_NET_T *p_ctx, char *name, size_t name_len ); |
215 | |
216 | /** Get the port of a stream server client, if connected. |
217 | * The port is written to the address in host order. |
218 | * Calling this function on a non-stream server instance, or one that is not |
219 | * connected to a client, will result in an error status. |
220 | * |
221 | * \param p_ctx The socket instance. |
222 | * \param port Pointer where the port should be written. |
223 | * \return The status of the socket. */ |
224 | vc_container_net_status_t vc_container_net_get_client_port( VC_CONTAINER_NET_T *p_ctx , unsigned short *port ); |
225 | |
226 | /** Perform a control operation on the socket. |
227 | * See vc_container_net_control_t for more details. |
228 | * |
229 | * \param p_ctx The socket instance. |
230 | * \param operation The control operation to perform. |
231 | * \param args Variable list of additional arguments to the operation. |
232 | * \return The status of the socket. */ |
233 | vc_container_net_status_t vc_container_net_control( VC_CONTAINER_NET_T *p_ctx, vc_container_net_control_t operation, va_list args); |
234 | |
235 | /** Convert a 32-bit unsigned value from network order (big endian) to host order. |
236 | * |
237 | * \param value The value to be converted. |
238 | * \return The converted value. */ |
239 | uint32_t vc_container_net_to_host( uint32_t value ); |
240 | |
241 | /** Convert a 32-bit unsigned value from host order to network order (big endian). |
242 | * |
243 | * \param value The value to be converted. |
244 | * \return The converted value. */ |
245 | uint32_t vc_container_net_from_host( uint32_t value ); |
246 | |
247 | /** Convert a 16-bit unsigned value from network order (big endian) to host order. |
248 | * |
249 | * \param value The value to be converted. |
250 | * \return The converted value. */ |
251 | uint16_t vc_container_net_to_host_16( uint16_t value ); |
252 | |
253 | /** Convert a 16-bit unsigned value from host order to network order (big endian). |
254 | * |
255 | * \param value The value to be converted. |
256 | * \return The converted value. */ |
257 | uint16_t vc_container_net_from_host_16( uint16_t value ); |
258 | |
259 | #ifdef __cplusplus |
260 | } |
261 | #endif |
262 | |
263 | #endif /* VC_NET_SOCKETS_H */ |
264 | |