nRF5 IoT SDK  v0.9.0
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
BSD Socket Interface

The BSD Socket Interface module is Nordic's implementation of the BSD Socket API, which is a set of standard function calls that can be used in an application. This module aims to be compatible with BSD sockets in order to simplify porting applications to use Nordic's nRF IoT SDK.

Currently, the IoT SDK has the client-side implemented with the following features supported:

  • TCP client
  • UDP client
  • Non-Blocking behavior (setting O_NONBLOCK using fcntl)
  • select for read events
Note
accept, listen, bind, setsockopt and getsockopt are not yet implemented. And a future release of the IoT SDK will also have the BSD Socket server-side implemented.

The BSD Socket Interface is layered on top of the transport protocols. It supports both Nordic's IPv6 stack (UDP) as well as the LwIP stack (TCP only). Only one of them can be compiled at a time. In addition, and by default, the BSD Socket Interface automatically configures the BLE configuration options for 6LoWPAN and the entire stack is initialized upon creating the first socket. See Configuration parameters for details.

See BSD Socket interface reference for the API documentation. See the IoT examples folder for socket UDP and TCP client examples that work with the LwIP TCP Server and Nordic IPv6 UDP Server examples. The socket examples are also compilable in a POSIX environment.

Blocking/Non-Blocking behavior

The BSD Socket Interface currently supports Blocking and Non-Blocking I/O. Blocking is defined as any operation that waits for resources provided by the network. Non-Blocking I/O is supported by setting O_NONBLOCK on the socket descriptor and using select. Currently, Non-Blocking I/O with select is only supported when reading data.

The following table lists the API calls and their default behavior.

API Blocking/Non-Blocking
socket Non-Blocking
connect TCP: Blocking, UDP: Non-Blocking
send Blocking
recv Blocking
close Non-Blocking
Note
Any of these calls can be made non-blocking by setting O_NONBLOCK using fcntl. The send and recv also allows MSG_DONTWAIT flag to be passed to use Non-Blocking I/O for a single operation.

Blocking I/O

Following is a simple socket client sending a single UDP packet.

#include <sys/socket.h>
#include <errno.h>
int main(void)
{
int s = socket(AF_INET6, SOCK_DGRAM, 0);
if (s < 0)
{
return 1;
}
struct sockaddr_in6 dest_addr;
memset(&dest_addr, 0, sizeof(dest_addr));
inet_pton(AF_INET6, "2001:db8::1", &dest_addr.sin6_addr);
dest_addr.sin6_port = htons(1234);
int ret = connect(s, &dest_addr, sizeof(dest_addr));
if (ret < 0)
{
return 2;
}
const char * msg = "Hello, Server!";
ssize_t nbytes = send(s, msg, strlen(msg));
if (nbytes != strlen(msg))
{
return 3;
}
ret = close(s);
if (ret < 0)
{
return 4;
}
return 0;
}

Non-Blocking I/O

Following is a simple socket client sending and receiving messages over TCP.

#include <sys/socket.h>
#include <errno.h>
int main(void)
{
int s = socket(AF_INET6, SOCK_STREAM, 0);
if (s < 0)
{
return 1;
}
struct sockaddr_in6 dest_addr;
memset(&dest_addr, 0, sizeof(dest_addr));
inet_pton(AF_INET6, "2001:db8::1", &dest_addr.sin6_addr);
dest_addr.sin6_port = htons(1234);
int ret = connect(s, &dest_addr, sizeof(dest_addr));
if (ret < 0)
{
return 2;
}
const char * msg = "Hello, Server!";
ssize_t nbytes = send(s, msg, strlen(msg));
if (nbytes != strlen(msg))
{
return 3;
}
nbytes = 0;
char buf[32];
while (nbytes < 0)
{
nbytes = recv(s, buf, sizeof(buf), MSG_DONTWAIT);
}
ret = close(s);
if (ret < 0)
{
return 4;
}
return 0;
}

Configuration parameters

Feature Description
SOCKET_IPV6_ENABLE Set to 1 to enable Nordic's IPv6 stack
SOCKET_LWIP_ENABLE Set to 1 to enable LwIP stack
SOCKET_MEDIUM_ENABLE Set to 1 to automatically configure link layer
SOCKET_LOGS_ENABLE Set to 1 to enable logging to UART (must set ENABLE_DEBUG_LOG_SUPPORT as well)
SOCKET_ENABLE_API_PARAM_CHECK Set to 1 to enable extra sanity checks

References