1 /***************************************************************************/ /**
2  * @file  sl_si91x_socket.h
3  *******************************************************************************
4  * # License
5  * <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
6  *******************************************************************************
7  *
8  * SPDX-License-Identifier: Zlib
9  *
10  * The licensor of this software is Silicon Laboratories Inc.
11  *
12  * This software is provided 'as-is', without any express or implied
13  * warranty. In no event will the authors be held liable for any damages
14  * arising from the use of this software.
15  *
16  * Permission is granted to anyone to use this software for any purpose,
17  * including commercial applications, and to alter it and redistribute it
18  * freely, subject to the following restrictions:
19  *
20  * 1. The origin of this software must not be misrepresented; you must not
21  *    claim that you wrote the original software. If you use this software
22  *    in a product, an acknowledgment in the product documentation would be
23  *    appreciated but is not required.
24  * 2. Altered source versions must be plainly marked as such, and must not be
25  *    misrepresented as being the original software.
26  * 3. This notice may not be removed or altered from any source distribution.
27  *
28  ******************************************************************************/
29 
30 #pragma once
31 #include "sl_si91x_socket_types.h"
32 
33 /**
34  * @addtogroup SI91X_SOCKET_FUNCTIONS
35  * @{
36  */
37 /**
38  * @brief Creates a new socket.
39  *
40  * @details
41  * The function creates a new socket and returns a file descriptor for the respective socket.
42  * The socket is used for communication within the specified protocol family,
43  * type, and protocol. The created socket is used for various network operations
44  * such as, connecting to a remote host, sending and receiving data, and so on.
45  *
46  * @param[in] family
47  *   Specifies the communication domain for the socket. This selects the protocol family to be used.
48  *   Accepts values from @ref BSD_SOCKET_FAMILIY. Currently, only @ref AF_INET and @ref AF_INET6 are supported.
49  *
50  * @param[in] type
51  *   Specifies the type of the socket, which determines the semantics of communication.
52  *   Accepts values from @ref BSD_SOCKET_TYPES. Currently, only @ref SOCK_STREAM and @ref SOCK_DGRAM are supported.
53  *
54  * @param[in] protocol
55  *   Specifies a particular protocol to be used with the socket.
56  *   Accepts values from @ref BSD_SOCKET_PROTOCOL. Currently, only @ref IPPROTO_TCP, @ref IPPROTO_UDP, and @ref IPPROTO_IP are supported.
57  *
58  * @return
59  *   Returns the socket ID or file descriptor for the newly created socket on success, or -1 on failure.
60  */
61 int sl_si91x_socket(int family, int type, int protocol);
62 
63 /**
64  * @brief Creates an asynchronous socket and registers the provided callback.
65  *
66  * @details
67  *    This function creates a new asynchronous socket and registers a callback function
68  *    that is called whenever data is received on the socket. The socket can be used
69  *    for communication within the specified protocol family, type, and protocol.
70  *
71  * @param[in] family Specifies the communication domain for the socket. This selects the protocol family to be used.
72  *                   Accepts values from @ref BSD_SOCKET_FAMILIY. Currently, only @ref AF_INET and @ref AF_INET6 are supported.
73  *
74  * @param[in] type Specifies the type of the socket, which determines the semantics of communication.
75  *                 Accepts values from @ref BSD_SOCKET_TYPES. Currently, only @ref SOCK_STREAM and @ref SOCK_DGRAM are supported.
76  *
77  * @param[in] protocol Specifies a particular protocol to be used with the socket.
78  *                     Accepts values from @ref BSD_SOCKET_PROTOCOL. Currently, only @ref IPPROTO_TCP, @ref IPPROTO_UDP, and @ref IPPROTO_IP are supported.
79  *
80  *  @param[in] callback A function pointer of type @ref sl_si91x_socket_receive_data_callback_t. This function is called when the socket receives data.
81  *
82  * @return Returns the socket ID or file descriptor for the newly created socket on success, or -1 on failure.
83  */
84 int sl_si91x_socket_async(int family, int type, int protocol, sl_si91x_socket_receive_data_callback_t callback);
85 
86 /**
87  * @brief Sets a specified socket option on the identified socket asynchronously.
88  *
89  * @details
90  * This function sets a specified option for a given socket asynchronously. The options
91  * can be set at various levels and include parameters such as receive timeout, maximum
92  * retries, maximum segment size, TCP keepalive, SSL options, and so on.
93  *
94  * @param[in] socket
95  *   The socket ID or file descriptor for the specified socket.
96  *
97  * @param[in] level
98  *   The option level. Accepts values from @ref BSD_SOCKET_OPTION_LEVEL.
99  *
100  * @param[in] option_name
101  *   The option to be configured. Accepts values from @ref SI91X_SOCKET_OPTION_NAME.
102  *   Currently, following options are supported:
103  *   - @ref SL_SI91X_SO_RCVTIME
104  *   - @ref SL_SI91X_SO_MAXRETRY
105  *   - @ref SL_SI91X_SO_MSS
106  *   - @ref SL_SI91X_SO_TCP_KEEPALIVE
107  *   - @ref SL_SI91X_SO_HIGH_PERFORMANCE_SOCKET
108  *   - @ref SL_SI91X_SO_SSL_ENABLE
109  *   - @ref SL_SI91X_SO_SSL_V_1_0_ENABLE
110  *   - @ref SL_SI91X_SO_SSL_V_1_1_ENABLE
111  *   - @ref SL_SI91X_SO_SSL_V_1_2_ENABLE
112  *   - @ref SL_SI91X_SO_SOCK_VAP_ID
113  *   - @ref SL_SI91X_SO_SSL_V_1_3_ENABLE
114  *   - @ref SL_SI91X_SO_CERT_INDEX
115  *   - @ref SL_SI91X_SO_TLS_SNI
116  *   - @ref SL_SI91X_SO_TLS_ALPN
117  *   - @ref SL_SI91X_SO_MAX_RETRANSMISSION_TIMEOUT_VALUE
118  *
119  * @param[in] option_value
120  *   The value of the parameter.
121  *   | option_name                                       | option_value                         |  description                                                                                                               |
122  *   |---------------------------------------------------|--------------------------------------|----------------------------------------------------------------------------------------------------------------------------|
123  *   | @ref SL_SI91X_SO_RCVTIME                          | sl_si91x_time_value                  | Socket Receive timeout. sl_si91x_time_value structure is used to represent time in two parts: seconds and microseconds.    |
124  *   | @ref SL_SI91X_SO_MAXRETRY                         | uint16_t                             | Maximum number of TCP retries                                                                                              |
125  *   | @ref SL_SI91X_SO_MSS                              | uint16_t                             | Maximum Segment Size (MSS) for the TCP connection                                                                          |
126  *   | @ref SL_SI91X_SO_TCP_KEEPALIVE                    | uint16_t                             | Set TCP keepalive in seconds                                                                                               |
127  *   | @ref SL_SI91X_SO_HIGH_PERFORMANCE_SOCKET          | BIT(7)                               | Set high performance socket                                                                                                |
128  *   | @ref SL_SI91X_SO_SSL_ENABLE                       | SL_SI91X_ENABLE_TLS                  | Enable TLS/SSL                                                                                                             |
129  *   | @ref SL_SI91X_SO_SSL_V_1_0_ENABLE                 | SL_SI91X_TLS_V_1_0                   | Enable TLS v1.0                                                                                                            |
130  *   | @ref SL_SI91X_SO_SSL_V_1_1_ENABLE                 | SL_SI91X_TLS_V_1_1                   | Enable TLS v1.1                                                                                                            |
131  *   | @ref SL_SI91X_SO_SSL_V_1_2_ENABLE                 | SL_SI91X_TLS_V_1_2                   | Enable TLS v1.2                                                                                                            |
132  *   | @ref SL_SI91X_SO_SSL_V_1_3_ENABLE                 | SL_SI91X_TLS_V_1_3                   | Enable TLS v1.3                                                                                                            |
133  *   | @ref SL_SI91X_SO_SOCK_VAP_ID                      | uint8_t                              | Specifies the interface on which the socket will operate                                                                   |
134  *   | @ref SL_SI91X_SO_CERT_INDEX                       | uint8_t                              | Certificate index                                                                                                          |
135  *   | @ref SL_SI91X_SO_TLS_SNI                          | sl_si91x_socket_type_length_value_t  | Server Name Indication (SNI)                                                                                               |
136  *   | @ref SL_SI91X_SO_TLS_ALPN                         | sl_si91x_socket_type_length_value_t  | Application-Layer Protocol Negotiation (ALPN)                                                                              |
137  *   | @ref SL_SI91X_SO_MAX_RETRANSMISSION_TIMEOUT_VALUE | uint8_t                              | Maximum retransmission timeout value for TCP                                                                               |
138  *
139  * @param[in] option_len
140  *   The length of the parameter of type @ref socklen_t.
141  *
142  * @return
143  *   Returns 0 on success, or -1 on failure.
144  *
145  * @note
146  * This function is used only for the SiWx91x socket API.
147  * The options set in this function will not be effective if called after `sl_si91x_connect()` or `sl_si91x_listen()` for TCP, or after `sl_si91x_sendto()`, `sl_si91x_recvfrom()`, or `sl_si91x_connect()` for UDP.
148  * The value of the option SL_SI91X_SO_MAX_RETRANSMISSION_TIMEOUT_VALUE should be a power of 2.
149  */
150 int sl_si91x_setsockopt(int32_t socket, int level, int option_name, const void *option_value, socklen_t option_len);
151 
152 /**
153  * @brief Assigns a local protocol address to a socket.
154  *
155  * @details
156  * The function binds a socket to a specific local address and port number.
157  * It is typically used on the server side to specify the port on which the server
158  * will listen for incoming connections.
159  *
160  * @param[in] socket
161  *   The socket ID or file descriptor for the specified socket.
162  *
163  * @param[in] addr
164  *   Pointer to a `struct sockaddr` contains the address to which the socket is bound.
165  *   This address specifies the local IP address and port number.
166  *
167  * @param[in] addr_len
168  *   The length of the socket address, in bytes, of type `socklen_t`.
169  *
170  * @return
171  *   Returns 0 on success, or -1 on failure.
172  */
173 int sl_si91x_bind(int socket, const struct sockaddr *addr, socklen_t addr_len);
174 
175 /**
176  * @brief Enables a socket to listen for remote connection requests in passive mode.
177  *
178  * @details
179  * The function configures a socket to listen for incoming connection requests.
180  * It is typically used on the server side after the socket has been bound to a local
181  * address using the `sl_si91x_bind` function. The socket enters passive mode,
182  * where it waits for remote clients to connect.
183  *
184  * @param[in] socket
185  *   The socket ID or file descriptor for the specified socket.
186  *
187  * @param[in] max_number_of_clients
188  *   The maximum number of pending connections which the socket can queue.
189  *
190  * @return
191  *   Returns 0 on success, or -1 on failure.
192  */
193 int sl_si91x_listen(int socket, int max_number_of_clients);
194 
195 /**
196  * @brief Accepts a connection request from a remote peer.
197  *
198  * @details
199  * The function blocks until a client attempts to connect to the server socket. After receiving a connection request, it proceeds.
200  *
201  * @param[in] socket The socket ID or file descriptor for the specified socket.
202  * @param[in] addr The address of type @ref sockaddr to which datagrams are to be sent.
203  * @param[in] addr_len The length of the socket address of type @ref socklen_t in bytes.
204  * @return int
205  */
206 int sl_si91x_accept(int socket, const struct sockaddr *addr, socklen_t addr_len);
207 
208 /**
209  * @brief
210  *  Accepts a connection request from the remote peer and registers a callback.
211  *
212  * @details
213  *  The function sets up the server socket to listen for incoming connections,
214  *  and immediately returns without blocking the main program's execution.
215  *
216  * @param[in] socket
217  *  The socket ID or file descriptor for the specified socket.
218  * @param[in] callback
219  *  A function pointer of type @ref sl_si91x_socket_accept_callback_t that is called when a new client is connected to the server.
220  * @return int
221  */
222 int sl_si91x_accept_async(int socket, sl_si91x_socket_accept_callback_t callback);
223 
224 /**
225  * @brief
226  * Initiates a connection to a remote socket specified by the addr parameter.
227  *
228  * @details
229  * The function initiates a connection to a remote socket specified by the `addr` parameter.
230  * It is typically used on the client side to establish a connection to a server.
231  *
232  * @param[in] socket
233  *  The socket ID or file descriptor for the specified socket.
234  * @param[in] addr
235  *  Address of type @ref sockaddr to which datagrams are to be sent.
236  * @param[in] addr_len
237  *  Length of the socket address of type @ref socklen_t in bytes.
238  * @return int
239  */
240 int sl_si91x_connect(int socket, const struct sockaddr *addr, socklen_t addr_len);
241 
242 /**
243  * @brief
244  * Sends the data to the remote peer on the given socket.
245  *
246  * @details
247  * This should be used only when the socket is in a connected state.
248  *
249  * @param[in] socket
250  * The socket ID or file descriptor for the specified socket.
251  * @param[in] buffer
252  * Pointer to the buffer containing data to send to the remote peer.
253  * @param[in] buffer_length
254  *  Length of the buffer pointed to by the buffer parameter.
255  * @param[in] flags
256  *  Controls the transmission of the data.
257  * @return int
258  * @note The flags parameter is not currently supported.
259  */
260 int sl_si91x_send(int socket, const uint8_t *buffer, size_t buffer_length, int32_t flags);
261 
262 /**
263  * @brief
264  * Transmits one or more messages to a socket asynchronously.
265  *
266  * @details
267  * This should be used only when the socket is in a connected state.
268  *
269  * @param[in] socket
270  * The socket ID or file descriptor for the specified socket.
271  * @param[in] buffer
272  * Pointer to the buffer containing data to send to the remote peer
273  * @param[in] buffer_length
274  *  Length of the buffer pointed to by the buffer parameter.
275  * @param[in] flags
276  *  Controls the transmission of the data.
277  * @param[in] callback
278  *  A function pointer of type @ref sl_si91x_socket_data_transfer_complete_handler_t that is called after complete data transfer.
279  * @return int
280  * @note The flags parameter is not currently supported.
281  */
282 int sl_si91x_send_async(int socket,
283                         const uint8_t *buffer,
284                         size_t buffer_length,
285                         int32_t flags,
286                         sl_si91x_socket_data_transfer_complete_handler_t callback);
287 
288 /**
289  * @brief
290  * Transmits one or more messages to another socket.
291  *
292  * @details
293  * The function is called from an unconnected socket, typically like a UDP socket.
294  *
295  * @param[in] socket
296  * The socket ID or file descriptor for the specified socket.
297  * @param[in] buffer
298  *  Pointer to data buffer contains data to send to remote peer.
299  * @param[in] buffer_length
300  *  Length of the buffer pointed to by the buffer parameter.
301  * @param[in] flags
302  *  Controls the transmission of the data.
303  * @param[in] addr
304  *  Address of type @ref sockaddr to which datagrams are to be sent.
305  * @param[in] addr_len
306  *  Length of the socket address of type @ref socklen_t in bytes.
307  * @return int
308  * @note The flags parameter is not currently supported.
309  */
310 int sl_si91x_sendto(int socket,
311                     const uint8_t *buffer,
312                     size_t buffer_length,
313                     int32_t flags,
314                     const struct sockaddr *addr,
315                     socklen_t addr_len);
316 
317 /**
318  * @brief
319  * Transmits one or more messages to another socket asynchronously, and receives acknowledgement through the registered callback.
320  *
321  * @details
322  * The function can also be called from an unconnected socket, typically like a UDP socket.
323  *
324  * @param[in] socket
325  * The socket ID or file descriptor for the specified socket.
326  * @param[in] buffer
327  *  Pointer to data buffer contains data to send to remote peer.
328  * @param[in] buffer_length
329  *  Length of the buffer pointed to by the buffer parameter.
330  * @param[in] flags
331  *  Controls the transmission of the data.
332  * @param[in] to_addr
333  *  Address of type @ref sockaddr to which datagrams are to be sent.
334  * @param[in] to_addr_len
335  *  Length of the socket address of type @ref socklen_t in bytes.
336  * @param[in] callback
337  *  A function pointer of type @ref sl_si91x_socket_data_transfer_complete_handler_t that is called after complete data transfer.
338  * @return int
339  * @note The flags parameter is not currently supported.
340  */
341 int sl_si91x_sendto_async(int socket,
342                           const uint8_t *buffer,
343                           size_t buffer_length,
344                           int32_t flags,
345                           const struct sockaddr *to_addr,
346                           socklen_t to_addr_len,
347                           sl_si91x_socket_data_transfer_complete_handler_t callback);
348 
349 /**
350  * @brief Sends data that is larger than the Maximum Segment Size (MSS).
351  *
352  * @details
353  * This function sends data that exceeds the MSS size to a remote peer. It handles
354  * the segmentation of the data into smaller chunks that fit within the MSS limit.
355  *
356  * @param[in] socket
357  *   The socket ID or file descriptor for the specified socket.
358  *
359  * @param[in] buffer
360  *   Pointer to the data buffer contains the data to be sent to the remote peer.
361  *
362  * @param[in] buffer_length
363  *   The length of the buffer pointed to by the buffer parameter.
364  *
365  * @param[in] flags
366  *   Controls the transmission of the data. Note that the flags parameter is not currently supported.
367  *
368  * @return
369  *   Returns the number of bytes sent on success, or -1 on failure.
370  */
371 int sl_si91x_send_large_data(int socket, const uint8_t *buffer, size_t buffer_length, int32_t flags);
372 
373 /**
374  * @brief Receives data from a connected socket.
375  *
376  * @details
377  * This function receives data from a connected socket and stores it in the specified buffer.
378  * It is typically used on the client or server side to read incoming data from a remote peer.
379  *
380  * @param[in] socket
381  *   The socket ID or file descriptor for the specified socket.
382  *
383  * @param[out] buffer
384  *   Pointer to the buffer holds the data received from the remote peer.
385  *
386  * @param[in] bufferLength
387  *   The length of the buffer pointed to by the buffer parameter.
388  *
389  * @param[in] flags
390  *   Controls the reception of the data. Note that the flags parameter are not currently supported.
391  *
392  * @return
393  *   Returns the number of bytes received on success, or -1 on failure.
394  */
395 int sl_si91x_recv(int socket, uint8_t *buffer, size_t bufferLength, int32_t flags);
396 
397 /**
398  * @brief Receives data from an unconnected socket, typically a UDP socket.
399  *
400  * @details
401  * This function receives data from an unconnected socket and stores it in the specified buffer.
402  * It is typically used to receive data from a remote peer without establishing a connection.
403  *
404  * @param[in] socket
405  *   The socket ID or file descriptor for the specified socket.
406  *
407  * @param[out] buffer
408  *   Pointer to the buffer that will hold the data received from the remote peer.
409  *
410  * @param[in] buffersize
411  *   The size of the buffer pointed to by the buffer parameter.
412  *
413  * @param[in] flags
414  *   Controls the reception of the data. Note that the flags parameter is not currently supported.
415  *
416  * @param[out] fromAddr
417  *   Pointer to a @ref sockaddr that will hold the address of the remote peer from which the current packet was received.
418  *
419  * @param[in, out] fromAddrLen
420  *   Pointer to a @ref socklen_t that contains the length of the remote peer address (fromAddr).
421  *   On return, it will contain the actual length of the address.
422  *
423  * @return
424  *   Returns the number of bytes received on success, or -1 on failure.
425  */
426 int sl_si91x_recvfrom(int socket,
427                       uint8_t *buffer,
428                       size_t buffersize,
429                       int32_t flags,
430                       struct sockaddr *fromAddr,
431                       socklen_t *fromAddrLen);
432 
433 /**
434  * @brief Disables send or receive operations on a socket.
435  *
436  * @details
437  * This function disables further send or receive operations on a specified socket.
438  * It can either close a specific socket or all sockets associated with a given port number.
439  *
440  * @param[in] socket
441  *   The socket ID or file descriptor for the specified socket that is to be closed.
442  *
443  * @param[in] how
444  *   Determines the scope of the shutdown operation:
445  *   - 0: Close the specified socket.
446  *   - 1: Close all sockets open on the specified socket's source port number.
447  *
448  * @return
449  *   Returns 0 on success, or -1 on failure.
450  *
451  * @note
452  *   If the socket is a server socket, the `how` parameter is ignored, and the socket is always closed based on the port number.
453  */
454 int sl_si91x_shutdown(int socket, int how);
455 
456 /**
457  * @brief
458  * The sl_si91x_select() function is used to monitor multiple file descriptors for readiness to
459  * perform I/O operations.  The file descriptors in the sets are monitored to
460  * see if they are ready for reading, ready for writing, or have an error
461  * condition pending.
462  * @details
463  * sl_si91x_select() allows a program to monitor multiple file descriptors,
464  * waiting until one or more of the file descriptors become "ready"
465  * for some class of I/O operation (e.g., input possible).  A file
466  * descriptor is considered ready if it is possible to perform a
467  * corresponding I/O operation without blocking.
468  *
469  * @param[in] nfds
470  *  The first nfds descriptors are checked in each set; that is, the descriptors from 0 through nfds-1.
471  * @param[in,out] readfds
472  *  A pointer to a fd_set object that specifies the descriptors to check for files that are ready for reading.
473  * @param[in,out] writefds
474  *  A pointer to a fd_set object that specifies the descriptors to check for files that are ready for writing.
475  * @param[in,out] exceptfds
476  *  A pointer to a fd_set object that will be watched for exceptions.
477  * @param[in] timeout
478  *  If timeout is provided, the device shall wait for timeout duration for the file descriptors to become ready.
479  *  If timeout is NULL, the device shall wait indefinitely for the file descriptors to become ready.
480  * @param[in] callback
481  *  A function pointer of type @ref sl_si91x_socket_select_callback_t that will be called when an asynchronous response  is received for a select request.
482  * @return
483  *  If callback is provided, the function will immediately return zero for success, and -1 for failure.
484  *  If callback is NULL, returns:
485  *  - total number of file descriptors set on success.
486  *  - 0 when no file descriptors are ready within the specified timeout.
487  *  - -1 on failure.
488  *
489  * @note
490  * The select function modifies the sets passed to it, so if the function
491  * is to be called again, the sets must be reinitialized.
492  * The exceptfds parameter is not currently supported.
493  */
494 int sl_si91x_select(int nfds,
495                     sl_si91x_fd_set *readfds,
496                     sl_si91x_fd_set *writefds,
497                     sl_si91x_fd_set *exceptfds,
498                     const struct timeval *timeout,
499                     sl_si91x_socket_select_callback_t callback);
500 
501 
502 /**
503  * @brief Registers a callback for remote socket termination events.
504  *
505  * @details
506  * This function registers a callback function is called when a remote socket is terminated.
507  * The callback function should be of type @ref sl_si91x_socket_remote_termination_callback_t.
508  *
509  * @param[in] callback
510  *   A valid function pointer of type @ref sl_si91x_socket_remote_termination_callback_t that is called when the remote socket is terminated.
511  */
512 void sl_si91x_set_remote_termination_callback(sl_si91x_socket_remote_termination_callback_t callback);
513 /** @} */
514