1/*
2Copyright (c) 2012, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, 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
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON 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
25SOFTWARE, 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
41extern "C" {
42#endif
43
44/** Status codes that can occur in a socket instance. */
45typedef 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 */
67typedef 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. */
79typedef 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/* @{ */
84typedef 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. */
125VC_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. */
133vc_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. */
139vc_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. */
154size_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. */
165size_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. */
174vc_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. */
186vc_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. */
194bool 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. */
202size_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. */
214vc_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. */
224vc_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. */
233vc_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. */
239uint32_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. */
245uint32_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. */
251uint16_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. */
257uint16_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