Wi-SUN Sockets#

The Wi-SUN socket API is loosely modeled after the well-known BSD socket API, also known as POSIX socket API. Each socket represents a handle for the local endpoint of a communication circuit.

v1.8 deprecates Silicon Labs socket API. For a seamless compatibility, refer to the Silicon Labs socket API (deprecated) software component.

API Overview#

BSD Function

Former Wi-SUN API Function

Description

socket()

sl_wisun_open_socket()

Creates an endpoint for communication and returns an Id that refers to that endpoint.

bind()

sl_wisun_bind_socket()

Bind a name to a socket.

listen()

sl_wisun_listen_on_socket()

Listen for connections on a socket.

connect()

sl_wisun_connect_socket()

Initiate a connection on a socket.

accept()

sl_wisun_accept_on_socket()

Accept a connection on a socket.

send()

sl_wisun_send_on_socket()

Send a message on a socket.

sendto()

sl_wisun_sendto_on_socket()

Send a message to a given address.

recv()

sl_wisun_receive_on_socket()

Receive a message from a socket.

recvfrom()

Not supported

Receive messages from a socket.

close()

sl_wisun_close_socket()

gethostbyname()

Not supported

gethostbyaddr()

Not supported

select()

Not supported

poll()

Not supported

getsockopt()

sl_wisun_get_socket_option()

Get socket option.

setsockopt()

sl_wisun_set_socket_option()

Set socket option designated by optname at a given protocol level to the value pointed by optval.

Socket Life Cycle#

In general, a socket is created by explicitly calling socket() and must be explicitly closed by calling close(). This both closes the communication circuit and frees any resources allocated to the socket.

In certain protocols, the communication circuit may be closed by the remote peer. This is indicated with a SL_WISUN_MSG_SOCKET_CLOSING_IND_ID event. Although the socket connection is closed, the system resources will not be freed until the application calls close().

Exchanging Data#

Certain protocols require a socket in a connected state, meaning the underlying protocol must first establish a session with the remote peer before data can be exchanged. It is also optionally possible on certain connectionless protocols. In either case, connecting a socket creates a direct communication link with a remote peer, allowing the socket to be used only with that particular peer.

To switch a socket into connected state, use connect(). See the table below for protocol details.

Protocol

Unconnected

Connected

IPPROTO_UDP

MAY

MAY

IPPROTO_TCP

MUST NOT

MUST

IPPROTO_ICMP

MUST

MUST NOT

Transmit#

When a socket is in unconnected state, sendto() is used to transmit data. The function requires the application to specify the remote peer address and port number on each call. When a socket is connected, send() is used instead. Because the socket is "locked" into a single remote peer, address and port number are not needed.

Both functions are asynchronous. A successful return code indicates the socket has buffered the provided data and the application may free the data resources. The application receives a SL_WISUN_MSG_SOCKET_DATA_SENT_IND_ID event when a part or all buffered data has been sent.

Receive#

To manage received socket data, the application has indication mode and polling mode. All sockets default to polling mode. In this mode, the application will receive a SL_WISUN_MSG_SOCKET_DATA_AVAILABLE_IND_ID event on data reception. The received data is stored in the socket buffer until the application reads it using recv() or recvfrom(); Both recv() or recvfrom() could be used only on the latter mode (Polling). A socket that generated a SL_WISUN_MSG_SOCKET_DATA_AVAILABLE_IND_ID will never block. In indication mode, the received data is sent as a SL_WISUN_MSG_SOCKET_DATA_IND_ID event as soon as it is received. The application must either handle the data immediately or store it for later processing. Either way, the socket will not keep the data once the event handler returns.

Blocking operations#

By default, socket operations block the RTOS task until its completion. Sockets can be configured as non-blocking or'ing SOCK_NONBLOCK flag to the type parameter of socket(), or using the socket option #O_NONBLOCK. Our implementation only supports one operation at a time.

Client#

TCP Example#

  1. Open a TCP socket using socket(AFINET_6, SOCK_STREAM, IPPROTO_TCP).

  2. Initiate connection to the remote server using connect().

  3. Wait for SL_WISUN_MSG_SOCKET_CONNECTED_IND_ID event.

  4. ... Exchange data with the remote server ...

  5. Close the socket using close().

UDP Example#

  1. Open an UDP socket using socket(AFINET_6, SOCK_DGRAM, IPPROTO_UDP).

  2. ... Exchange data with the remote server ...

  3. Close the socket using close().

Server#

TCP Example#

  1. Open a TCP socket using socket(AFINET_6, SOCK_STREAM, IPPROTO_TCP).

  2. Set the server socket port number using bind().

  3. Set the server socket into listening state using listen().

  4. Wait for SL_WISUN_MSG_SOCKET_CONNECTION_AVAILABLE_IND_ID event.

  5. Accept the client connection using accept() on the server socket.

  6. ... Exchange data with the remote client using the newly created client socket ...

  7. Close the client socket using close().

  8. Go to 4.

UDP Example#

  1. Open an UDP socket using socket(AFINET_6, SOCK_DGRAM, IPPROTO_UDP).

  2. Set the socket port number using bind().

  3. ... Exchange data with the remote client ...