aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket')
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/README.md28
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/arpa/inet.h45
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/netinet/in.h45
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/socket_api.h593
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/select.h45
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/socket.h45
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/unistd.h82
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/sleep.c53
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket.c746
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_common.h115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_config.h81
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_trace.h102
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/transport_if.h161
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.c227
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.h120
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/addr_util/inet_pton.c60
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.c176
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.h170
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.c122
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.h146
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.c185
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.h123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/platform/ble/socket_ble.c50
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/ipv6/transport_handler.c387
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/lwip/transport_handler.c630
25 files changed, 4537 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/README.md b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/README.md
new file mode 100644
index 0000000..9ec0b8d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/README.md
@@ -0,0 +1,28 @@
+# Socket module
+
+The socket module contains the BSD socket implementation for the IoT SDK. The purpose of the socket
+API is to
+
+* Provide a common API for all platforms
+* Simplify porting of pc network applications
+
+The socket API hides details of the underlying transport, but supports proprietary extensions for
+controlling configuration settings and using underlying transport layers.
+
+<pre>
+socket/
+ api/ - Public socket API headers
+ common/ - Common implementation of API and implementation code shared by all platforms (main socket API implementation, with hooks for different transports)
+ libraries/ - Generic libraries that are not tied to a specific platform
+ portdb/ - Port database to track and allocate socket ports
+ addr_util/ - Common address utilities
+ mbuf/ - Memory buffer utilities
+ transport/ - Transport/network stack hooks
+ ipv6/ - Nordic IPv6 stack transport hook
+ lwip/ - LwIP transport hook
+ test/ - Integration tests shared between transport stacks
+ platform/ - Platform specific code
+ ble/ - BLE specific code (only wrappers around sd_ble_app_evt_())
+ config/ - Configuration socket implementations
+ medium/ - Medium configuration socket implementation
+</pre>
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/arpa/inet.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/arpa/inet.h
new file mode 100644
index 0000000..c1749d3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/arpa/inet.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef SOCKET_ARPA_INET_H__
+#define SOCKET_ARPA_INET_H__
+
+#include "socket_api.h"
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/netinet/in.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/netinet/in.h
new file mode 100644
index 0000000..bfcf881
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/netinet/in.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef SOCKET_NETINET_IN_H__
+#define SOCKET_NETINET_IN_H__
+
+#include "socket_api.h"
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/socket_api.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/socket_api.h
new file mode 100644
index 0000000..37e50d4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/socket_api.h
@@ -0,0 +1,593 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file socket_api.h
+ *
+ * @defgroup iot_socket BSD Socket interface
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Nordic socket interface for IoT.
+ *
+ * @details This module provides the socket interface for writing IoT applications. The API is
+ * designed to be compatible with the POSIX/BSD socket interface for the purpose of
+ * making porting easy. The socket options API has been extended to support configuring
+ * Nordic BLE stack, tuning of RF parameters as well as security options.
+ */
+#ifndef SOCKET_API_H__
+#define SOCKET_API_H__
+
+#include <stdint.h>
+
+#include "sdk_common.h"
+#include "iot_defines.h"
+#include "errno.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(__GNUC__) || (__GNUC__ == 0)
+typedef int32_t ssize_t;
+#else
+#include <sys/types.h>
+#ifdef __SES_ARM
+typedef int32_t ssize_t;
+#endif
+#endif
+
+#ifndef htons
+#define htons(x) HTONS(x) /**< Convert byte order from host to network (short). */
+#endif
+
+#ifndef htonl
+#define htonl(x) HTONL(x) /**< Convert byte order from host to network (long). */
+#endif
+
+#ifndef ntohs
+#define ntohs(x) NTOHS(x) /**< Convert byte order from network to host (short). */
+#endif
+
+#ifndef ntohl
+#define ntohl(x) NTOHL(x) /**< Convert byte order from network to host (long). */
+#endif
+
+/**@defgroup socket_families Values for socket_family_t
+ * @ingroup iot_socket
+ * @{
+ */
+#define AF_INET 2 /**< IPv4 socket family. */
+#define AF_INET6 10 /**< IPv6 socket family. */
+#if defined(NRF52) || defined(NRF52_SERIES)
+#define AF_NRF_CFG 39 /**< nRF configuration socket.*/
+#endif
+/**@} */
+
+/**@defgroup socket_types Values for socket_type_t
+ * @ingroup iot_socket
+ * @{
+ */
+#define SOCK_STREAM 1 /**< TCP socket type. */
+#define SOCK_DGRAM 2 /**< UDP socket type. */
+/**@} */
+
+/**@defgroup socket_protocols Values for socket_protocol_t
+ * @ingroup iot_socket
+ * @{
+ */
+#define IPPROTO_TCP 1 /**< Use TCP as transport protocol. */
+#define IPPROTO_UDP 2 /**< Use UDP as transport protocol. */
+/**@} */
+
+/**@defgroup socket_send_recv_flags Socket send/recv flags
+ * @ingroup iot_socket
+ * @{
+ */
+#define MSG_DONTROUTE 0x01 /**< Send only to hosts on directly connected networks. */
+#define MSG_DONTWAIT 0x02 /**< Enables non-blocking operation. */
+#define MSG_OOB 0x04 /**< Sends out-of-band data on sockets that support this. */
+#define MSG_PEEK 0x08 /**< Return data from the beginning of receive queue without removing data from the queue. */
+#define MSG_WAITALL 0x10 /**< Request a blocking operation until the request is satisfied. */
+/**@} */
+
+#if defined(NRF52) || defined(NRF52_SERIES)
+/**
+ * @defgroup socket_option_levels Values for socket_opt_lvl_t
+ * @ingroup iot_socket
+ * @{
+ */
+#define SOL_SOCKET 1 /**< Standard socket options. */
+#define SOL_NRF_MEDIUM 2 /**< Nordic medium socket options. Use this to control medium parameters. */
+/**@} */
+
+/**@defgroup socket_medium_options Medium socket option level types
+ * @ingroup iot_socket
+ * @{
+ */
+#define MEDIUM_INIT_PARAMS 1 /**< Medium initialization parameters. */
+/**@}
+ */
+#endif
+
+/**@defgroup fcnt_commands fcntl commands
+ * @ingroup iot_socket
+ * @{
+ */
+#define F_SETFL 1 /**< Set flag. */
+#define F_GETFL 2 /**< Get flag. */
+/**@} */
+
+/**@defgroup fcnt_flags fcntl flags
+ * @ingroup iot_socket
+ * @{
+ */
+#define O_NONBLOCK 0x01 /**< Use non-blocking I/O. */
+/**@} */
+
+/**
+ * @brief Socket module size type.
+ */
+typedef uint32_t socklen_t;
+
+/**
+ * @brief Socket port type.
+ */
+typedef uint16_t in_port_t;
+
+/**
+ * @brief Structure specifying time interval.
+ */
+struct timeval
+{
+ uint32_t tv_sec; /**< Time interval seconds. */
+ uint32_t tv_usec; /**< Time interval microseconds. */
+};
+
+/**
+ * @brief Socket families.
+ *
+ * @details For a list of valid values, refer to @ref socket_families.
+ */
+typedef int socket_family_t;
+typedef socket_family_t sa_family_t;
+
+/**
+ * @brief Socket types.
+ *
+ * @details For a list of valid values refer to @ref socket_types.
+ */
+typedef int socket_type_t;
+
+/**
+ * @brief Socket protocols.
+ *
+ * @details Use 0 if you do not want do specify socket protocol, which should be sufficient for most users.
+ * Other values are only provided for socket API compatibility, see @ref socket_protocols.
+ */
+typedef int socket_protocol_t;
+
+/**
+ * @if (IOT)
+ * @brief Socket option levels.
+ *
+ * @details For a list of valid values, refer to @ref socket_option_levels.
+ * @endif
+ */
+typedef int socket_opt_lvl_t;
+
+/**
+ * @brief Generic socket address.
+ *
+ * @details Only provided for API compatibility.
+ */
+struct sockaddr
+{
+ uint8_t sa_len;
+ socket_family_t sa_family;
+ char sa_data[];
+};
+
+/**
+ * @brief IPv6 address.
+ */
+struct in6_addr
+{
+ uint8_t s6_addr[16];
+};
+
+/**
+ * @brief IPv4 address.
+ */
+typedef uint32_t in_addr_t;
+
+/**
+ * @brief IPv4 address structure.
+ */
+struct in_addr
+{
+ in_addr_t s_addr;
+};
+
+/**
+ * @brief Global IPv6 any-address.
+ */
+extern const struct in6_addr in6addr_any;
+
+/**
+ * @brief Global IPv4 any-address.
+ */
+extern const struct in_addr inaddr_any;
+
+/**
+ * @brief Address record for IPv6 addresses.
+ *
+ * @details Contains the address and port of the host, as well as other socket options. All fields
+ * in this structure are compatible with the POSIX variant for API compatibility.
+ */
+struct sockaddr_in6
+{
+ uint8_t sin6_len; /**< Length of this data structure. */
+ sa_family_t sin6_family; /**< Socket family. */
+ in_port_t sin6_port; /**< Port, in network byte order. */
+
+ uint32_t sin6_flowinfo; /**< IPv6 flow info parameters. Not used. */
+ struct in6_addr sin6_addr; /**< IPv6 address. */
+ uint32_t sin6_scope_id; /**< IPv6 scope ID. Not used. */
+};
+
+/**
+ * @brief Address record for IPv4 addresses.
+ *
+ * @details Contains the address and port of the host. All fields
+ * in this structure are compatible with the POSIX variant for API compatibility.
+ */
+struct sockaddr_in
+{
+ uint8_t sin_len; /**< Length of this data structure. */
+ sa_family_t sin_family; /**< Socket family. */
+ in_port_t sin_port; /**< Port, in network byte order. */
+
+ struct in_addr sin_addr; /**< IPv4 address. */
+};
+
+typedef struct sockaddr sockaddr_t;
+typedef struct sockaddr_in6 sockaddr_in6_t;
+typedef struct in6_addr in6_addr_t;
+typedef struct sockaddr_in sockaddr_in_t;
+
+/**
+ * @brief Function for creating a socket.
+ *
+ * @details API to create a socket that can be used for network communication independently
+ * of lower protocol layers.
+ *
+ * @param[in] family The protocol family of the network protocol to use. Currently, only
+ * AF_INET6 is supported.
+ * @param[in] type The protocol type to use for this socket.
+ * @param[in] protocol The transport protocol to use for this socket.
+ *
+ * @return A non-negative socket descriptor on success, or -1 on error.
+ */
+int socket(socket_family_t family, socket_type_t type, socket_protocol_t protocol);
+
+/**
+ * @brief Function for closing a socket and freeing any resources held by it.
+ *
+ * @details If the socket is already closed, this function is a noop.
+ *
+ * @param[in] sock The socket to close.
+ *
+ * @return 0 on success, or -1 on error.
+ */
+int close(int sock);
+
+/**
+ * @brief Function for controlling file descriptor options.
+ *
+ * @details Set or get file descriptor options or flags. For a list of supported commands, refer to @ref fcnt_commands.
+ * For a list of supported flags, refer to @ref fcnt_flags.
+ *
+ * @param[in] fd The descriptor to set options on.
+ * @param[in] cmd The command class for options.
+ * @param[in] flags The flags to set.
+ */
+int fcntl(int fd, int cmd, int flags);
+
+/**
+ * @brief Function for connecting to an endpoint with a given address.
+ *
+ * @details The socket handle must be a valid handle that has not yet been connected. Running
+ * connect on a connected handle will return an error.
+ *
+ * @param[in] sock The socket to use for connection.
+ * @param[in] p_servaddr The address of the server to connect to. Currently, sockaddr_in6 is
+ * the only supported type.
+ * @param[in] addrlen The size of the p_servaddr argument.
+ *
+ * @return 0 on success, or -1 on error.
+ */
+int connect(int sock, const void * p_servaddr, socklen_t addrlen);
+
+/**
+ * @brief Function for sending data through a socket.
+ *
+ * @details By default, this function will block unless the O_NONBLOCK
+ * socket option has been set, OR MSG_DONTWAIT is passed as a flag. In that case, the
+ * method will return immediately.
+ *
+ * @param[in] sock The socket to write data to.
+ * @param[in] p_buff Buffer containing the data to send.
+ * @param[in] nbytes Size of data contained on p_buff.
+ * @param[in] flags Flags to control send behavior.
+ *
+ * @return The number of bytes that were sent on success, or -1 on error.
+ */
+ssize_t send(int sock, const void * p_buff, size_t nbytes, int flags);
+
+/**
+ * @brief Function for sending datagram through a socket.
+ *
+ * @details By default, this function will block if the lower layers are not able to process the
+ * packet, unless the O_NONBLOCK socket option has been set, OR MSG_DONTWAIT is passed as a flag.
+ * In that case, the method will return immediately.
+ *
+ * @param[in] sock The socket to write data to.
+ * @param[in] p_buff Buffer containing the data to send.
+ * @param[in] nbytes Size of data contained in p_buff.
+ * @param[in] flags Flags to control send behavior.
+ * @param[in] p_servaddr The address of the server to send to. Currently, sockaddr_in6 is
+ * the only supported type.
+ * @param[in] addrlen The size of the p_servaddr argument.
+ *
+ * @return The number of bytes that were sent on success, or -1 on error.
+ */
+ssize_t sendto(int sock,
+ const void * p_buff,
+ size_t nbytes,
+ int flags,
+ const void * p_servaddr,
+ socklen_t addrlen);
+
+/**
+ * @brief Function for writing data to a socket. See \ref send() for details.
+ *
+ * @param[in] sock The socket to write data to.
+ * @param[in] p_buff Buffer containing the data to send.
+ * @param[in] nbytes Size of data contained in p_buff.
+ *
+ * @return The number of bytes that were sent on success, or -1 on error.
+ */
+ssize_t write(int sock, const void * p_buff, size_t nbytes);
+
+/**
+ * @brief Function for receiving data on a socket.
+ *
+ * @details API for receiving data from a socket. By default, this function will block, unless the
+ * O_NONBLOCK socket option has been set, or MSG_DONTWAIT is passed as a flag.
+ *
+ * @param[in] sock The socket to receive data from.
+ * @param[out] p_buff Buffer to hold the data to be read.
+ * @param[in] nbytes Number of bytes to read. Should not be larger than the size of p_buff.
+ * @param[in] flags Flags to control receive behavior.
+ *
+ * @return The number of bytes that were read, or -1 on error.
+ */
+ssize_t recv(int sock, void * p_buff, size_t nbytes, int flags);
+
+/**
+ * @brief Function for receiving datagram on a socket.
+ *
+ * @details API for receiving data from a socket. By default, this function will block, unless the
+ * O_NONBLOCK socket option has been set, or MSG_DONTWAIT is passed as a flag.
+ *
+ * @param[in] sock The socket to receive data from.
+ * @param[out] p_buff Buffer to hold the data to be read.
+ * @param[in] nbytes Number of bytes to read. Should not be larger than the size of p_buff.
+ * @param[in] flags Flags to control receive behavior.
+ * @param[out] p_cliaddr Socket address that will be set to the client's address.
+ * @param[inout] p_addrlen The size of the p_cliaddr passed. Might be modified by the function.
+ *
+ * @return The number of bytes that were read, or -1 on error.
+ */
+ssize_t recvfrom(int sock,
+ void * p_buff,
+ size_t nbytes,
+ int flags,
+ void * p_cliaddr,
+ socklen_t * p_addrlen);
+
+/**
+ * @brief Function for reading data from a socket. See \ref recv() for details.
+ *
+ * @param[in] sock The socket to receive data from.
+ * @param[out] p_buff Buffer to hold the data to be read.
+ * @param[in] nbytes Number of bytes to read. Should not be larger than the size of p_buff.
+ *
+ * @return The number of bytes that were read, or -1 on error.
+ */
+ssize_t read(int sock, void * p_buff, size_t nbytes);
+
+/**
+ * @defgroup fd_set_api API for file descriptor set
+ * @ingroup iot_socket
+ * @details File descriptor sets are used as input to the select() function for doing I/O
+ * multiplexing. The maximum number of descriptors contained in a set is defined by
+ * FD_SETSIZE.
+ *
+ * @{
+ */
+#ifndef FD_ZERO
+
+typedef uint32_t fd_set;
+#define FD_ZERO(set) (*(set) = 0) /**< Clear the entire set. */
+#define FD_SET(fd, set) (*(set) |= (1u << (fd))) /**< Set a bit in the set. */
+#define FD_CLR(fd, set) (*(set) &= ~(1u << (fd))) /**< Clear a bit in the set. */
+#define FD_ISSET(fd, set) (*(set) & (1u << (fd))) /**< Check if a bit in the set is set. */
+#define FD_SETSIZE sizeof(fd_set) /**< The max size of a set. */
+
+#endif
+/**@} */
+
+/**
+ * @brief Function for waiting for read, write, or exception events on a socket.
+ *
+ * @details Wait for a set of socket descriptors to be ready for reading, writing, or having
+ * exceptions. The set of socket descriptors is configured before calling this function.
+ * This function will block until any of the descriptors in the set has any of the required
+ * events. This function is mostly useful when using O_NONBLOCK or MSG_DONTWAIT options
+ * to enable async operation.
+ *
+ * @param[in] nfds The highest socket descriptor value contained in the sets.
+ * @param[inout] p_readset The set of descriptors for which to wait for read events. Set to NULL
+ * if not used.
+ * @param[inout] p_writeset The set of descriptors for which to wait for write events. Set to NULL
+ * if not used.
+ * @param[inout] p_exceptset The set of descriptors for which to wait for exception events. Set to
+ * NULL if not used.
+ * @param[in] p_timeout The timeout to use for select call. Set to NULL if waiting forever.
+ *
+ * @return The number of ready descriptors contained in the descriptor sets on success, or -1 on error.
+ */
+int select(int nfds,
+ fd_set * p_readset,
+ fd_set * p_writeset,
+ fd_set * p_exceptset,
+ const struct timeval * p_timeout);
+
+/**
+ * @brief Function for setting socket options for a given socket.
+ *
+ * @details The options are grouped by level, and the option value should be the expected for the
+ * given option, and the lifetime must be longer than that of the socket.
+ *
+ * @param[in] sock The socket for which to set the option.
+ * @param[in] level The level or group to which the option belongs.
+ * @param[in] optname The name of the socket option.
+ * @param[in] p_optval The value to be stored for this option.
+ * @param[in] optlen The size of p_optval.
+ *
+ * @return 0 on success, or -1 on error.
+ */
+int setsockopt(int sock,
+ socket_opt_lvl_t level,
+ int optname,
+ const void * p_optval,
+ socklen_t optlen);
+
+/**
+ * @brief Function for getting socket options for a given socket.
+ *
+ * @details The options are grouped by level, and the option value is the value described by the
+ * option name.
+ *
+ * @param[in] sock The socket for which to set the option.
+ * @param[in] level The level or group to which the option belongs.
+ * @param[in] optname The name of the socket option.
+ * @param[out] p_optval Pointer to the storage for the option value.
+ * @param[inout] p_optlen The size of p_optval. Can be modified to the actual size of p_optval.
+ *
+ * @return 0 on success, or -1 on error.
+ */
+int getsockopt(int sock,
+ socket_opt_lvl_t level,
+ int optname,
+ void * p_optval,
+ socklen_t * p_optlen);
+
+/**
+ * @brief Function for binding a socket to an address and port.
+ *
+ * @details The provided address must be supported by the socket protocol family.
+ *
+ * @param[in] sock The socket descriptor to bind.
+ * @param[in] p_myaddr The address to bind this socket to.
+ * @param[in] addrlen The size of p_myaddr.
+ *
+ * @return 0 on success, or -1 on error.
+ */
+int bind(int sock, const void * p_myaddr, socklen_t addrlen);
+
+/**
+ * @brief Function for marking a socket as listenable.
+ *
+ * @details Once a socket is marked as listenable, it cannot be unmarked. It is important to
+ * consider the backlog parameter, as it will affect how much memory your application will
+ * use in the worst case.
+ *
+ * @param[in] sock The socket descriptor on which to set the listening options.
+ * @param[in] backlog The max length of the queue of pending connections. A value of 0 means
+ * infinite.
+ *
+ * @return 0 on success, or -1 on error.
+ */
+int listen(int sock, int backlog);
+
+/**
+ * @brief Function for waiting for the next client to connect.
+ *
+ * @details This function will block if there are no clients attempting to connect.
+ *
+ * @param[in] sock The socket descriptor to use for waiting on client connections.
+ * @param[out] p_cliaddr Socket address that will be set to the client's address.
+ * @param[out] p_addrlen The size of the p_cliaddr passed. Might be modified by the function.
+ *
+ * @return A non-negative client descriptor on success, or -1 on error.
+ */
+int accept(int sock, void * p_cliaddr, socklen_t * p_addrlen);
+
+/**
+ * @brief Function for converting a human-readable IP address to a form usable by the socket API.
+ *
+ * @details This function will convert a string form of addresses and encode it into a byte array.
+ *
+ * @param[in] af Address family. Only AF_INET6 supported.
+ * @param[in] p_src Null-terminated string containing the address to convert.
+ * @param[out] p_dst Pointer to a struct in6_addr where the address will be stored.
+ *
+ * @return 1 on success, 0 if src does not contain a valid address, -1 if af is not a valid address
+ * family.
+ */
+int inet_pton(socket_family_t af, const char * p_src, void * p_dst);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //SOCKET_API_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/select.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/select.h
new file mode 100644
index 0000000..3fb05fb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/select.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef SOCKET_SYS_SELECT_H__
+#define SOCKET_SYS_SELECT_H__
+
+#include "socket_api.h"
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/socket.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/socket.h
new file mode 100644
index 0000000..c01fc3e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/socket.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef SOCKET_SYS_SOCKET_H__
+#define SOCKET_SYS_SOCKET_H__
+
+#include "socket_api.h"
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/unistd.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/unistd.h
new file mode 100644
index 0000000..ac77bdf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/unistd.h
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file unistd.h
+ *
+ * @defgroup iot_posix_unistd POSIX operating system API
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief POSIX standard functions.
+ */
+#ifndef SOCKET_UNISTD_H__
+#define SOCKET_UNISTD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief POSIX sleep function.
+ *
+ * @note Uses busy looping nrf_delay.
+ *
+ * @param[in] seconds The number of seconds to sleep.
+ *
+ * @return The number of seconds slept.
+ */
+unsigned int sleep(unsigned int seconds);
+
+/**
+ * @brief POSIX usleep function.
+ *
+ * @note Uses busy looping nrf_delay.
+ *
+ * @param[in] useconds The number of microseconds to sleep.
+ *
+ * @return The number of microseconds slept.
+ */
+unsigned int usleep(unsigned int useconds);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SOCKET_UNISTD_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/sleep.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/sleep.c
new file mode 100644
index 0000000..94dd07a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/sleep.c
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "unistd.h"
+#include "nrf_delay.h"
+
+unsigned int sleep(unsigned int seconds)
+{
+ nrf_delay_ms(seconds * 1000);
+ return seconds;
+}
+
+unsigned int usleep(unsigned int useconds)
+{
+ nrf_delay_ms(useconds / 1000);
+ return useconds;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket.c
new file mode 100644
index 0000000..fe7d6ca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket.c
@@ -0,0 +1,746 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nordic_common.h"
+#include "sdk_common.h"
+#include "sdk_config.h"
+#include "nrf_sdm.h"
+#include "app_scheduler.h"
+#include "app_timer.h"
+#include "iot_common.h"
+#include "app_error.h"
+#include "socket_api.h"
+#include "socket_common.h"
+#include "socket_trace.h"
+#include "sdk_os.h"
+#include "transport_if.h"
+#include "portdb.h"
+#include "errno.h"
+#include "mem_manager.h"
+#include "ipv6_parse.h"
+#include "netinet/in.h"
+#include "unistd.h"
+#include "sdk_os.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_log_default_backends.h"
+
+#ifndef SOCKET_ENABLE_API_PARAM_CHECK
+#define SOCKET_ENABLE_API_PARAM_CHECK 0
+#endif
+
+#include "socket_config.h"
+
+#if SOCKET_CONFIG_LOG_ENABLED == 1
+ NRF_LOG_MODULE_REGISTER();
+#endif
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * SOCKET_ENABLE_API_PARAM_CHECK should be set to 0 to disable these checks.
+ *
+ * @{
+ */
+#if SOCKET_ENABLE_API_PARAM_CHECK == 1
+
+/**@brief Macro to check is module is initialized before requesting one of the module procedures. */
+#define VERIFY_MODULE_IS_INITIALIZED() \
+ do { \
+ if (m_initialization_state == false) \
+ { \
+ return (SDK_ERR_MODULE_NOT_INITIALIZED | IOT_SOCKET_ERR_BASE);\
+ } \
+ } while (0)
+
+
+/**
+ * @brief Verify NULL parameters are not passed to API by application.
+ */
+#define NULL_PARAM_CHECK(PARAM) \
+ do { \
+ if ((PARAM) == NULL) \
+ { \
+ set_errno(EFAULT); \
+ return -1; \
+ } \
+ } while (0)
+
+/**
+ * @brief Verify socket id passed on the API by application is valid.
+ */
+#define VERIFY_SOCKET_ID(ID) \
+ do { \
+ if (((ID) < 0) || ((ID) >= NUM_SOCKETS)) \
+ { \
+ set_errno(EBADF); \
+ return -1; \
+ } \
+ } while (0)
+
+
+#else
+
+#define VERIFY_MODULE_IS_INITIALIZED()
+#define NULL_PARAM_CHECK(PARAM)
+#define VERIFY_SOCKET_ID(ID)
+#endif
+
+/** @} */
+#define SOCKET_MUTEX_INIT() SDK_MUTEX_INIT(m_socket_mtx);
+#define SOCKET_MUTEX_LOCK() SDK_MUTEX_LOCK(m_socket_mtx)
+#define SOCKET_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_socket_mtx)
+// note: one extra for configuration socket
+#define NUM_SOCKETS SOCKET_MAX_SOCKET_COUNT + 1
+
+SDK_MUTEX_DEFINE(m_socket_mtx) /**< Mutex for protecting m_socket_table (not individual entries). */
+
+#define SCHED_QUEUE_SIZE 16 /**< Maximum number of events in the scheduler queue. */
+#define SCHED_MAX_EVENT_DATA_SIZE 192 /**< Maximum size of scheduler events. */
+
+static bool m_initialization_state = false; /**< Variable to maintain module initialization state. */
+static volatile bool m_interface_up = false; /**< Interface state. */
+static socket_t m_socket_table[NUM_SOCKETS]; /**< Socket table. */
+
+const struct in6_addr in6addr_any = { {0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /**< IPv6 anycast address. */
+ 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u} };
+
+#if defined (NRF_LOG_ENABLED) && (NRF_LOG_ENABLED == 1)
+
+void log_init(void)
+{
+ ret_code_t err_code = NRF_LOG_INIT(NULL);
+ APP_ERROR_CHECK(err_code);
+
+ NRF_LOG_DEFAULT_BACKENDS_INIT();
+}
+
+#else // defined (NRF_LOG_ENABLED) && (NRF_LOG_ENABLED == 1)
+
+void log_init(void)
+{
+ ;
+}
+
+#endif // defined (NRF_LOG_ENABLED) && (NRF_LOG_ENABLED == 1)
+
+uint32_t socket_init(void)
+{
+ memset(m_socket_table, 0, sizeof(m_socket_table));
+
+ SOCKET_MUTEX_INIT();
+
+ log_init();
+
+ uint32_t err_code = nrf_mem_init();
+ APP_ERROR_CHECK(err_code);
+
+ APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
+
+ err_code = app_timer_init();
+ APP_ERROR_CHECK(err_code);
+
+ err_code = config_socket_init();
+ APP_ERROR_CHECK(err_code);
+
+#if SOCKET_TRANSPORT_ENABLE == 1
+ err_code = portdb_init(SOCKET_MAX_SOCKET_COUNT);
+ APP_ERROR_CHECK(err_code);
+
+ transport_handler_init();
+#endif
+ config_socket_start();
+ m_initialization_state = true;
+
+ SOCKET_TRACE("Socket init complete");
+
+ return NRF_SUCCESS;
+}
+
+/**
+ * Finds a free entry in the socket table, marks it as used and returns it. Returns -1 if no entry
+ * was found.
+ */
+static int socket_allocate(socket_t ** pp_socket)
+{
+ int ret_sock = -1;
+ SOCKET_MUTEX_LOCK();
+ for (int sock = 0; sock < NUM_SOCKETS; sock++)
+ {
+ SOCKET_TRACE("Looking at socket %d with state %d", (int)sock, m_socket_table[sock].so_state);
+ if (m_socket_table[sock].so_state == STATE_CLOSED)
+ {
+ m_socket_table[sock].so_state = STATE_OPEN;
+ ret_sock = sock;
+ *pp_socket = &m_socket_table[sock];
+ break;
+ }
+ }
+ if (ret_sock < 0)
+ {
+ set_errno(EMFILE);
+ }
+ SOCKET_MUTEX_UNLOCK();
+ return ret_sock;
+}
+
+static socket_t * socket_find(int sock)
+{
+ SOCKET_MUTEX_LOCK();
+ socket_t * p_socket = &m_socket_table[sock];
+ SOCKET_MUTEX_UNLOCK();
+ return p_socket;
+}
+
+static void socket_free(int sock)
+{
+ SOCKET_TRACE("Freeing socket %d", (int)sock);
+ SOCKET_MUTEX_LOCK();
+ memset(&m_socket_table[sock], 0, sizeof(m_socket_table[sock]));
+ m_socket_table[sock].so_state = STATE_CLOSED;
+ SOCKET_MUTEX_UNLOCK();
+}
+
+#if SOCKET_TRANSPORT_ENABLE == 1
+void transport_interface_up(void)
+{
+ m_interface_up = true;
+}
+
+void transport_interface_down(void)
+{
+ m_interface_up = false;
+ for (int sock = 0; sock < NUM_SOCKETS; sock++)
+ {
+ (void) close(sock);
+ }
+}
+#endif
+
+int fcntl(int fd, int cmd, int flags)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(fd);
+
+ if (!((cmd == F_SETFL) || (cmd == F_GETFL)))
+ {
+ set_errno(EINVAL);
+ return -1;
+ }
+ socket_t * p_socket = socket_find(fd);
+
+ if (cmd == F_SETFL)
+ {
+ p_socket->so_flags = flags;
+ }
+ else if (cmd == F_GETFL)
+ {
+ return p_socket->so_flags;
+ }
+
+ return 0;
+}
+
+static void socket_set_errno(uint32_t err_code)
+{
+ switch (err_code) {
+ case UDP_INTERFACE_NOT_READY: // fallthrough
+ case SOCKET_INTERFACE_NOT_READY:
+ set_errno(ENETDOWN);
+ break;
+ case SOCKET_WOULD_BLOCK:
+ set_errno(EAGAIN);
+ break;
+ case SOCKET_NO_ROUTE:
+ set_errno(ENETUNREACH);
+ break;
+ case NRF_ERROR_NO_MEM: // fallthrough
+ case SOCKET_NO_MEM:
+ set_errno(ENOMEM);
+ break;
+ case SOCKET_TIMEOUT:
+ set_errno(ETIMEDOUT);
+ break;
+ case SOCKET_NO_AVAILABLE_PORTS:
+ set_errno(EMFILE);
+ break;
+ case SOCKET_PORT_IN_USE: // fallthrough
+ case SOCKET_ADDRESS_IN_USE:
+ set_errno(EADDRINUSE);
+ break;
+ case SOCKET_INVALID_PARAM:
+ set_errno(EINVAL);
+ break;
+ case SOCKET_UNSUPPORTED_PROTOCOL:
+ set_errno(EPROTONOSUPPORT);
+ break;
+ case SOCKET_NOT_CONNECTED:
+ set_errno(ENOTCONN);
+ break;
+ }
+}
+
+
+int socket(socket_family_t family, socket_type_t type, socket_protocol_t protocol)
+{
+ if (m_initialization_state == false)
+ {
+ (void) socket_init();
+ }
+ VERIFY_MODULE_IS_INITIALIZED();
+
+ int ret_sock = -1;
+ socket_t * p_socket = NULL;
+ int sock = socket_allocate(&p_socket);
+ SOCKET_TRACE("Got value %d from allocate", (int)sock);
+ if (sock >= 0)
+ {
+ p_socket->so_params.so_family = family;
+ p_socket->so_params.so_protocol = protocol;
+ p_socket->so_params.so_type = type;
+ p_socket->so_transport = NULL;
+
+ if (family == AF_INET6)
+ {
+#if SOCKET_TRANSPORT_ENABLE == 1
+ p_socket->so_transport = &transport_impl;
+#else
+ set_errno(EAFNOSUPPORT);
+#endif
+ }
+ else if (family == AF_NRF_CFG || family == AF_NRF_CFG_INTERNAL)
+ {
+ p_socket->so_transport = &config_socket_transport;
+ }
+ else
+ {
+ set_errno(EAFNOSUPPORT);
+ }
+
+ if (p_socket->so_transport != NULL)
+ {
+ uint32_t err_code = p_socket->so_transport->open(p_socket);
+ socket_set_errno(err_code);
+ ret_sock = (err_code == NRF_SUCCESS) ? sock : ret_sock;
+ }
+
+ if (ret_sock < 0)
+ {
+ socket_free(sock);
+ }
+ }
+ SOCKET_TRACE("Returning socket value %d", (int)ret_sock);
+ return ret_sock;
+}
+
+static uint32_t wait_interface_up(void)
+{
+ SOCKET_TRACE("Waiting for interface to come up");
+ uint32_t err_code = NRF_SUCCESS;
+ while (err_code == NRF_SUCCESS && m_interface_up == false)
+ {
+ err_code = socket_wait();
+ }
+ if (m_interface_up == true)
+ {
+ SOCKET_TRACE("Interface is up!");
+ }
+ return err_code;
+}
+
+static uint32_t socket_interface_up(bool is_blocking)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ if (m_interface_up == false)
+ {
+ if (is_blocking)
+ {
+ (void) wait_interface_up();
+ }
+ }
+ if (m_interface_up == false)
+ {
+ err_code = SOCKET_INTERFACE_NOT_READY;
+ }
+ return err_code;
+}
+
+int connect(int sock, const void * p_addr, socklen_t addrlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+ NULL_PARAM_CHECK(p_addr);
+
+ socket_t * p_socket = socket_find(sock);
+ bool is_blocking = ((p_socket->so_flags & O_NONBLOCK) == 0);
+ int ret = -1;
+
+ uint32_t err_code = socket_interface_up(is_blocking);
+ if (err_code != NRF_SUCCESS)
+ {
+ socket_set_errno(err_code);
+ }
+ else if (p_socket->so_state == STATE_OPEN)
+ {
+ err_code = p_socket->so_transport->connect(p_socket, p_addr, addrlen);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_socket->so_state = STATE_CONNECTED;
+ ret = 0;
+ }
+ socket_set_errno(err_code);
+ }
+ else if (p_socket->so_state == STATE_CONNECTED)
+ {
+ set_errno(EISCONN);
+ }
+ else if (p_socket->so_state == STATE_CLOSED)
+ {
+ set_errno(EBADF);
+ }
+ return ret;
+}
+
+
+ssize_t sendto(int sock,
+ const void * p_buf,
+ size_t buflen,
+ int flags,
+ const void * p_servaddr,
+ socklen_t addrlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+ NULL_PARAM_CHECK(p_buf);
+
+ socket_t * p_socket = socket_find(sock);
+
+ if ((p_socket->so_flags & O_NONBLOCK) != 0 &&
+ (flags & MSG_WAITALL) == 0)
+ {
+ flags |= MSG_DONTWAIT;
+ }
+
+ uint32_t err_code = socket_interface_up(((p_socket->so_flags & O_NONBLOCK) == 0) || ((flags & MSG_DONTWAIT) == 0));
+
+ ssize_t ret = -1;
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = p_socket->so_transport->send(p_socket, p_buf, buflen, flags, p_servaddr, addrlen);
+ if (err_code == NRF_SUCCESS)
+ {
+ ret = (ssize_t) buflen;
+ }
+ }
+ socket_set_errno(err_code);
+ return ret;
+}
+
+ssize_t send(int sock, const void * p_buf, size_t buflen, int flags)
+{
+ return sendto(sock, p_buf, buflen, flags, NULL, 0);
+}
+
+ssize_t write(int sock, const void * p_buf, size_t buflen)
+{
+ return send(sock, p_buf, buflen, 0);
+}
+
+ssize_t recvfrom(int sock,
+ void * p_buf,
+ size_t buf_size,
+ int flags,
+ void * p_cliaddr,
+ socklen_t * p_addrlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+ NULL_PARAM_CHECK(p_buf);
+
+ socket_t * p_socket = socket_find(sock);
+ ssize_t ret = -1;
+ uint32_t recv_size = buf_size;
+
+ uint32_t err_code = p_socket->so_transport->recv(p_socket,
+ p_buf,
+ &recv_size,
+ flags,
+ p_cliaddr,
+ p_addrlen);
+ if (err_code == NRF_SUCCESS)
+ {
+ ret = (ssize_t) recv_size;
+ }
+ socket_set_errno(err_code);
+ return ret;
+}
+
+ssize_t recv(int sock, void * p_buf, size_t buf_size, int flags)
+{
+ return recvfrom(sock, p_buf, buf_size, flags, NULL, NULL);
+}
+
+ssize_t read(int sock, void * p_buf, size_t buf_size)
+{
+ return recv(sock, p_buf, buf_size, 0);
+}
+
+int setsockopt(int sock,
+ socket_opt_lvl_t level,
+ int optname,
+ const void * p_optval,
+ socklen_t optlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+
+ socket_t * p_socket = socket_find(sock);
+
+ uint32_t err_code = p_socket->so_transport->setsockopt(p_socket,
+ level,
+ optname,
+ p_optval,
+ optlen);
+ socket_set_errno(err_code);
+ return (err_code == NRF_SUCCESS ? 0 : -1);
+}
+
+int getsockopt(int sock, socket_opt_lvl_t level, int optname, void * p_optval, socklen_t * p_optlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+
+ socket_t * p_socket = socket_find(sock);
+
+ uint32_t err_code = p_socket->so_transport->getsockopt(p_socket,
+ level,
+ optname,
+ p_optval,
+ p_optlen);
+ socket_set_errno(err_code);
+ return (err_code == NRF_SUCCESS ? 0 : -1);
+}
+
+int bind(int sock, const void * p_addr, socklen_t addrlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+ NULL_PARAM_CHECK(p_addr);
+
+ socket_t * p_socket = socket_find(sock);
+ bool is_blocking = ((p_socket->so_flags & O_NONBLOCK) == 0);
+ int ret = -1;
+
+ uint32_t err_code = socket_interface_up(is_blocking);
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = p_socket->so_transport->bind(p_socket, p_addr, addrlen);
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ ret = 0;
+ }
+ socket_set_errno(err_code);
+ return ret;
+}
+
+int listen(int sock, int backlog)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+
+ socket_t * p_socket = socket_find(sock);
+
+ uint32_t err_code = p_socket->so_transport->listen(p_socket, backlog);
+ return (err_code == NRF_SUCCESS ? 0 : -1);
+}
+
+int accept(int sock, void * p_cliaddr, socklen_t * p_addrlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+ NULL_PARAM_CHECK(p_cliaddr);
+ NULL_PARAM_CHECK(p_addrlen);
+
+ socket_t * p_socket = socket_find(sock);
+ int ret = -1;
+
+ if (p_socket->so_params.so_type != SOCK_STREAM)
+ {
+ set_errno(EOPNOTSUPP);
+ }
+ else
+ {
+ uint32_t err_code = NRF_SUCCESS;
+ socket_t * p_client = NULL;
+ int sock_cli = socket_allocate(&p_client);
+ if (sock_cli >= 0)
+ {
+ p_client->so_params = p_socket->so_params;
+ p_client->so_state = STATE_CONNECTED;
+ p_client->so_transport = p_socket->so_transport;
+ err_code = p_socket->so_transport->accept(p_socket, p_client, p_cliaddr, p_addrlen);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ ret = sock_cli;
+ }
+ else
+ {
+ socket_set_errno(err_code);
+ socket_free(sock_cli);
+ }
+ }
+ return ret;
+}
+
+int close(int sock)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+
+ socket_t * p_socket = socket_find(sock);
+ int ret = 0;
+
+ if (p_socket->so_state != STATE_CLOSED)
+ {
+ uint32_t err_code = p_socket->so_transport->close(p_socket);
+ ret = (err_code == NRF_SUCCESS) ? 0 : -1;
+ SOCKET_TRACE("Close socket %d: ret: %d", (int)sock, ret);
+ socket_free(sock);
+ }
+ return ret;
+}
+
+int fd_set_cmp(fd_set * set_a, fd_set * set_b)
+{
+ int ret = 0;
+ if (set_a != NULL && set_b != NULL)
+ {
+ for (uint32_t i = 0; i < FD_SETSIZE; i++)
+ {
+ if (FD_ISSET(i, set_a) != FD_ISSET(i, set_b))
+ {
+ ret = 1;
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+int select(int nfds,
+ fd_set * p_readset,
+ fd_set * p_writeset,
+ fd_set * p_exceptset,
+ const struct timeval * p_timeout)
+{
+ VERIFY_SOCKET_ID(nfds - 1);
+
+ // Approximately 10 ms sleep between each iteration
+ uint32_t timestep = 10000;
+ uint32_t endtime = 0;
+ if (p_timeout != NULL)
+ {
+ endtime = (p_timeout->tv_sec * 1000000) + p_timeout->tv_usec;
+ }
+ fd_set readset;
+ FD_ZERO(&readset);
+ fd_set writeset;
+ FD_ZERO(&writeset);
+ fd_set exceptset;
+ FD_ZERO(&exceptset);
+
+#define SELECT_CHECK_SET(in_set, out_set, evt_var) \
+ if ((in_set) != NULL) \
+ { \
+ if (FD_ISSET(sock, (in_set)) && (evt_var) > 0) \
+ { \
+ FD_SET(sock, (out_set)); \
+ num_ready++; \
+ } \
+ else \
+ { \
+ FD_CLR(sock, (out_set)); \
+ } \
+ }
+
+ int num_ready = 0;
+ uint32_t err_code = NRF_SUCCESS;
+ while (err_code == NRF_SUCCESS)
+ {
+ for (int sock = 0; sock < nfds; sock++)
+ {
+ socket_t * p_socket = socket_find(sock);
+ SELECT_CHECK_SET(p_readset, &readset, p_socket->so_read_evt);
+ SELECT_CHECK_SET(p_writeset, &writeset, p_socket->so_write_evt);
+ SELECT_CHECK_SET(p_exceptset, &exceptset, p_socket->so_except_evt);
+ }
+ // TODO: Check out how app events queue up while we checked the socket
+ if (fd_set_cmp(p_readset, &readset) == 0 &&
+ fd_set_cmp(p_writeset, &writeset) == 0 &&
+ fd_set_cmp(p_exceptset, &exceptset) == 0)
+
+ {
+ break;
+ }
+ else
+ {
+ if (p_timeout == NULL)
+ {
+ err_code = socket_wait();
+ }
+ else if (endtime - timestep < endtime)
+ {
+ (void) usleep(timestep);
+ endtime -= timestep;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ }
+
+ return num_ready;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_common.h
new file mode 100644
index 0000000..d9a0f8a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_common.h
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file socket_common.h
+ *
+ * @defgroup socket_common BSD Socket internal functions and structures
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Nordic socket interface internal functions and structures.
+ */
+#ifndef SOCKET_COMMON_H__
+#define SOCKET_COMMON_H__
+
+#include <stdint.h>
+#include "socket_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct socket_transport;
+
+#define AF_NRF_CFG_INTERNAL 41 /**< Socket family type, internal NRF configuration socket. */
+
+/**
+ * @brief Function for initializing the socket API module.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code is returned.
+ */
+uint32_t socket_init(void);
+
+/**
+ * @brief Waiting function for sockets.
+ *
+ * @details Must be implemented by specific modules such as BLEs.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code is returned.
+ */
+uint32_t socket_wait(void);
+
+/**
+ * @brief Create parameters for a socket.
+ */
+typedef struct {
+ socket_family_t so_family; /**< Socket family. */
+ socket_protocol_t so_protocol; /**< Socket protocol. */
+ socket_type_t so_type; /**< Socket type. */
+} socket_params_t;
+
+/**
+ * @brief Different states a socket can be in.
+ */
+typedef enum {
+ STATE_CLOSED = 0, /**< Socket is closed. */
+ STATE_OPEN, /**< Socket is opened. */
+ STATE_CONNECTED, /**< Socket is connected. */
+} socket_state_t;
+
+/**
+ * @brief The state associated with a socket handle.
+ */
+typedef struct {
+ socket_params_t so_params; /**< Generic socket parameters. */
+ void * so_ctx; /**< Transport specific context. */
+ int so_flags; /**< Socket flags. */
+ uint16_t so_read_evt; /**< Notifying of read events. */
+ uint16_t so_write_evt; /**< Notifying of write events. */
+ uint16_t so_except_evt; /**< Notifying of exceptional events. */
+ struct socket_transport * so_transport; /**< Transport attached to this socket. */
+ volatile socket_state_t so_state; /**< Socket state. */
+} socket_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SOCKET_COMMON_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_config.h
new file mode 100644
index 0000000..cce571e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_config.h
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file socket_config.h
+ *
+ * @defgroup iot_socket_config Configuration socket API
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Configuration socket API.
+ *
+ * This API is used internally by the socket handling to support the configuration
+ * socket type. The configuration socket is implemented using a special transport hook, which is
+ * implemented differently depending on the platform.
+ */
+#ifndef SOCKET_CONFIG_H__
+#define SOCKET_CONFIG_H__
+
+#include "socket_common.h"
+#include "transport_if.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for setting the default configuration.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t config_socket_init(void);
+
+/**
+ * @brief Function for starting the configuration layer.
+ */
+void config_socket_start(void);
+
+extern socket_transport_t config_socket_transport;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SOCKET_CONFIG_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_trace.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_trace.h
new file mode 100644
index 0000000..87fafdf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_trace.h
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file socket_trace.h
+ *
+ * @defgroup iot_socket_debug_log Module's log macros
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Socket trace macros.
+ *
+ * @details Macros for creating module logs which can be useful in understanding the handling
+ * of events or actions on API requests. These are intended for debugging purposes and
+ * can be disabled by defining the SOCKET_CONFIG_LOG_ENABLED.
+ * @note If NRF_LOG_ENABLED is disabled, SOCKET_CONFIG_LOG_ENABLED has no effect.
+ */
+#ifndef SOCKET_TRACE_H__
+#define SOCKET_TRACE_H__
+
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if SOCKET_CONFIG_LOG_ENABLED == 1
+#if defined (NRF_LOG_ENABLED) && (NRF_LOG_ENABLED == 1)
+
+#define NRF_LOG_MODULE_NAME socket
+
+#define NRF_LOG_LEVEL SOCKET_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR SOCKET_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR SOCKET_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+
+#define SOCKET_TRACE NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define SOCKET_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define SOCKET_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#else
+
+#define SOCKET_TRACE(...) \
+ do { \
+ (void) fprintf( stderr, "socket: " ); \
+ (void) fprintf( stderr, __VA_ARGS__ ); \
+ (void) fprintf( stderr, "\r\n" ); \
+ } while (0)
+
+#endif
+
+#else // SOCKET_CONFIG_LOG_ENABLED
+
+#define SOCKET_TRACE(...) /**< Disables traces. */
+#define SOCKET_ERR(...) /**< Disables error logs. */
+#define SOCKET_DUMP(...) /**< Disables dumping of octet streams. */
+
+#endif // SOCKET_CONFIG_LOG_ENABLED
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SOCKET_TRACE_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/transport_if.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/transport_if.h
new file mode 100644
index 0000000..75a86c1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/transport_if.h
@@ -0,0 +1,161 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file transport_if.h
+ *
+ * @defgroup iot_socket_transport_if Transport implementation interface
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Transport implementation interface.
+ *
+ * The transport interface defines the hook to be used for socket transport. The implementation of
+ * this interface would be different across platforms and event IP stacks (i.e. Nordic IPv6 vs LwIP).
+ */
+#ifndef TRANSPORT_IF_H__
+#define TRANSPORT_IF_H__
+
+#include "iot_defines.h"
+#include "socket_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for opening a socket.
+ */
+typedef uint32_t (*tr_open_t) (socket_t * p_socket);
+
+/**
+ * @brief Function for connecting a socket to an address.
+ */
+typedef uint32_t (*tr_connect_t)(socket_t * p_socket, const void * p_addr, socklen_t addrlen);
+
+/**
+ * @brief Function for sending data on a socket.
+ */
+typedef uint32_t (*tr_send_t)(socket_t * p_socket,
+ const void * p_buf,
+ uint32_t len,
+ int flags,
+ const void * p_destaddr,
+ socklen_t destaddr_len);
+
+/**
+ * @brief Function for receiving data from a socket.
+ */
+typedef uint32_t (*tr_recv_t)(socket_t * p_socket,
+ void * p_buf,
+ uint32_t * sz,
+ int flags,
+ void * p_srcaddr,
+ socklen_t * p_srcaddr_len);
+
+/**
+ * @brief Function for binding a socket to an address and port.
+ */
+typedef uint32_t (*tr_bind_t)(socket_t * p_socket, const void * p_addr, socklen_t addrlen);
+
+/**
+ * @brief Function for listening on a socket.
+ */
+typedef uint32_t (*tr_listen_t)(socket_t * p_socket, int backlog);
+
+/**
+ * @brief Function for accepting a connection on a socket.
+ */
+typedef uint32_t (*tr_accept_t)(socket_t * p_socket,
+ socket_t * p_client,
+ void * p_client_addr,
+ socklen_t * p_client_addr_len);
+
+/**
+ * @brief Function for closing a socket.
+ */
+typedef uint32_t (*tr_close_t)(socket_t * p_socket);
+
+/**
+ * @brief Function for setting options on a socket.
+ */
+typedef uint32_t (*tr_setsockopt_t)(socket_t * p_socket,
+ int level,
+ int optname,
+ const void * p_optval,
+ socklen_t optlen);
+
+/**
+ * @brief Function for getting options from a socket.
+ */
+typedef uint32_t (*tr_getsockopt_t)(socket_t * p_socket,
+ int level,
+ int optname,
+ void * p_optval,
+ socklen_t * p_optlen);
+
+/**
+ * @brief The transport interface.
+ */
+typedef struct socket_transport
+{
+ tr_open_t open; /**< Open a socket. */
+ tr_connect_t connect; /**< Connect a socket to an address. */
+ tr_send_t send; /**< Send data on a socket. */
+ tr_recv_t recv; /**< Receive data from a socket. */
+ tr_bind_t bind; /**< Bind a socket to an address and port. */
+ tr_listen_t listen; /**< Listen on a socket. */
+ tr_accept_t accept; /**< Accept connection on a socket. */
+ tr_close_t close; /**< Close a socket. */
+ tr_setsockopt_t setsockopt; /**< Set options on a socket. */
+ tr_getsockopt_t getsockopt; /**< Get options from a socket. */
+} socket_transport_t;
+
+#if SOCKET_TRANSPORT_ENABLE == 1
+extern socket_transport_t transport_impl;
+void transport_handler_init(void);
+void transport_interface_up(void);
+void transport_interface_down(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TRANSPORT_IF_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.c
new file mode 100644
index 0000000..6b883dd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.c
@@ -0,0 +1,227 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_config.h"
+#include "socket_api.h"
+#include "config_medium.h"
+#include "ipv6_medium.h"
+#include "iot_errors.h"
+#include "app_error.h"
+#include "socket_config.h"
+
+static ipv6_medium_instance_t m_ipv6_medium; /**< IPv6 medium instance. */
+eui64_t eui64_local_iid; /**< Local EUI64 value that is used as the IID for*/
+
+eui64_t * config_medium_local_iid(void)
+{
+ return &eui64_local_iid;
+}
+
+void config_medium_start(void)
+{
+ uint32_t err_code = ipv6_medium_connectable_mode_enter(m_ipv6_medium.ipv6_medium_instance_id);
+ APP_ERROR_CHECK(err_code);
+}
+
+static void on_ipv6_medium_evt(ipv6_medium_evt_t * p_ipv6_medium_evt)
+{
+ switch (p_ipv6_medium_evt->ipv6_medium_evt_id)
+ {
+ case IPV6_MEDIUM_EVT_CONN_UP:
+ {
+ // TODO: Signal
+ break;
+ }
+ case IPV6_MEDIUM_EVT_CONN_DOWN:
+ {
+ config_medium_start();
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+static void on_ipv6_medium_error(ipv6_medium_error_t * p_ipv6_medium_error)
+{
+ // Do something.
+}
+
+static uint32_t config_medium_init(ipv6_medium_init_params_t * p_medium_params,
+ ipv6_medium_type_t medium_type)
+{
+ uint32_t err_code = ipv6_medium_init(p_medium_params, medium_type, &m_ipv6_medium);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ eui48_t ipv6_medium_eui48;
+ err_code = ipv6_medium_eui48_get(m_ipv6_medium.ipv6_medium_instance_id, &ipv6_medium_eui48);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ ipv6_medium_eui48.identifier[EUI_48_SIZE - 1] = 0x00;
+
+ err_code = ipv6_medium_eui48_set(m_ipv6_medium.ipv6_medium_instance_id, &ipv6_medium_eui48);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = ipv6_medium_eui64_get(m_ipv6_medium.ipv6_medium_instance_id, &eui64_local_iid);
+ return err_code;
+}
+
+uint32_t config_medium_init_default(void)
+{
+ static ipv6_medium_init_params_t ipv6_medium_init_params;
+ memset(&ipv6_medium_init_params, 0x00, sizeof(ipv6_medium_init_params));
+ ipv6_medium_init_params.ipv6_medium_evt_handler = on_ipv6_medium_evt;
+ ipv6_medium_init_params.ipv6_medium_error_handler = on_ipv6_medium_error;
+ return config_medium_init(&ipv6_medium_init_params, IPV6_MEDIUM_ID_BLE);
+}
+
+uint32_t config_medium_setopt(int optname, const void * p_optarg, socklen_t optlen)
+{
+ uint32_t err_code = SOCKET_INVALID_PARAM;
+ if (optname == MEDIUM_INIT_PARAMS)
+ {
+ if (optlen == sizeof(config_medium_params_t))
+ {
+ const config_medium_params_t * p_cfg = (const config_medium_params_t *)p_optarg;
+ ipv6_medium_init_params_t ipv6_medium_init_params;
+ memset(&ipv6_medium_init_params, 0x00, sizeof(ipv6_medium_init_params));
+ ipv6_medium_init_params.ipv6_medium_evt_handler = p_cfg->evt_handler;
+ ipv6_medium_init_params.ipv6_medium_error_handler = p_cfg->error_handler;
+ err_code = config_medium_init(&ipv6_medium_init_params, p_cfg->medium_type);
+ }
+ }
+ return err_code;
+}
+
+uint32_t config_medium_getopt(int optname, void * p_optarg, socklen_t * p_optlen)
+{
+ (void) optname;
+ (void) p_optarg;
+ (void) p_optlen;
+ return SOCKET_INVALID_PARAM;
+}
+
+uint32_t config_socket_init(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+#if SOCKET_AUTOINIT_ENABLE == 1
+ err_code = config_medium_init_default();
+#endif
+ return err_code;
+}
+
+void config_socket_start(void)
+{
+#if SOCKET_AUTOINIT_ENABLE == 1
+ config_medium_start();
+#endif
+}
+
+static uint32_t config_socket_open(socket_t * p_socket)
+{
+ (void) p_socket;
+ return NRF_ERROR_NULL;
+}
+
+static uint32_t config_socket_close(socket_t * p_socket)
+{
+ (void) p_socket;
+ return NRF_ERROR_NULL;
+}
+
+uint32_t config_socket_setopt(socket_t * p_socket,
+ int level,
+ int optname,
+ const void * p_optarg,
+ socklen_t optlen)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ switch (level)
+ {
+ case SOL_NRF_MEDIUM:
+ err_code = config_medium_setopt(optname, p_optarg, optlen);
+ break;
+ default:
+ err_code = SOCKET_INVALID_PARAM;
+ break;
+ }
+ return err_code;
+}
+
+uint32_t config_socket_getopt(socket_t * p_socket,
+ int level,
+ int optname,
+ void * p_optarg,
+ socklen_t * p_optlen)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ switch (level)
+ {
+ case SOL_NRF_MEDIUM:
+ err_code = config_medium_getopt(optname, p_optarg, p_optlen);
+ break;
+ default:
+ err_code = SOCKET_INVALID_PARAM;
+ break;
+ }
+ return err_code;
+}
+
+/**
+ * @brief Transport for configuration socket.
+ */
+socket_transport_t config_socket_transport =
+{
+ .open = config_socket_open,
+ .setsockopt = config_socket_setopt,
+ .getsockopt = config_socket_getopt,
+ .close = config_socket_close
+};
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.h
new file mode 100644
index 0000000..e4b7c01
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.h
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file config_medium.h
+ *
+ * @defgroup iot_socket_config_medium Configuration socket based on ipv6_medium
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Configuration socket based on the ipv6_medium module.
+ *
+ * This module wraps the medium module in a configuration socket API.
+ */
+#ifndef CONFIG_MEDIUM_H__
+#define CONFIG_MEDIUM_H__
+
+#include <stdint.h>
+#include "iot_defines.h"
+#include "ipv6_medium.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for initializing a configuration socket with default settings.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t config_medium_init_default(void);
+
+/**
+ * @brief Function for starting the medium layer.
+ *
+ * For BLE, this means to start advertising.
+ */
+void config_medium_start(void);
+
+/**
+ * @brief Function for retrieving local interface ID assigned.
+ *
+ * @return Pointer to location of interface ID.
+ */
+eui64_t * config_medium_local_iid(void);
+
+/**
+ * @brief Function for setting configuration parameters for the medium layers using the socket option.
+ *
+ * @param optname Option name/type.
+ * @param p_optarg Pointer to option value.
+ * @param optlen Length of option value.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t config_medium_setopt(int optname, const void * p_optarg, socklen_t optlen);
+
+/**
+ * @brief Function for getting configuration parameters for the medium layers using the socket option.
+ *
+ * @param optname Option name/type.
+ * @param p_optarg Pointer to the option value structure where the value should be stored.
+ * @param p_optlen Length of option value.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t config_medium_getopt(int optname, void * p_optarg, socklen_t * p_optlen);
+
+/**
+ * @brief Parameters passed for the MEDIUM_INIT_PARAMS option.
+ *
+ * These are currently the same as for ipv6_medium initialization.
+ */
+typedef struct {
+ ipv6_medium_evt_handler_t evt_handler; /**< The medium event handler callback. */
+ ipv6_medium_error_handler_t error_handler; /**< The medium error handler callback. */
+ ipv6_medium_type_t medium_type; /**< The medium type. */
+} config_medium_params_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CONFIG_MEDIUM_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/addr_util/inet_pton.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/addr_util/inet_pton.c
new file mode 100644
index 0000000..2fd1f4c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/addr_util/inet_pton.c
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "socket_api.h"
+#include "ipv6_parse.h"
+
+int inet_pton(socket_family_t af, const char * p_src, void * p_dst)
+{
+ int ret_val = 1;
+ if (af != AF_INET6)
+ {
+ ret_val = -1;
+ }
+ else
+ {
+ in6_addr_t * p_addr = (in6_addr_t *)p_dst;
+ uint32_t err_code = ipv6_parse_addr(p_addr->s6_addr, p_src, strlen(p_src));
+ if (err_code != NRF_SUCCESS)
+ {
+ ret_val = 0;
+ }
+ }
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.c
new file mode 100644
index 0000000..1458b01
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.c
@@ -0,0 +1,176 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "iot_defines.h"
+#include "iot_errors.h"
+#include "nrf_fifo.h"
+#include "mem_manager.h"
+#include "nrf.h"
+
+static __INLINE uint32_t fifo_inc(nrf_fifo_t * p_fifo, uint32_t pos)
+{
+ return (pos + 1) % p_fifo->nmemb;
+}
+
+static __INLINE bool fifo_full(nrf_fifo_t * p_fifo)
+{
+ return fifo_inc(p_fifo, p_fifo->write_pos) == p_fifo->read_pos;
+}
+
+static __INLINE bool fifo_empty(nrf_fifo_t * p_fifo)
+{
+ return p_fifo->read_pos == p_fifo->write_pos;
+}
+
+static __INLINE void fifo_enq(nrf_fifo_t * p_fifo, void * p_ctx)
+{
+ p_fifo->pp_elements[p_fifo->write_pos] = p_ctx;
+ __DSB();
+ p_fifo->write_pos = fifo_inc(p_fifo, p_fifo->write_pos);
+}
+
+
+static __INLINE void fifo_deq(nrf_fifo_t * p_fifo, void ** pp_ctx)
+{
+ *pp_ctx = p_fifo->pp_elements[p_fifo->read_pos];
+ __DSB();
+ p_fifo->read_pos = fifo_inc(p_fifo, p_fifo->read_pos);
+}
+
+uint32_t nrf_fifo_init(nrf_fifo_t * p_fifo, uint32_t nmemb, fifo_wait_fn wait_fn, fifo_flush_fn flush_fn)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t nmemb_actual = nmemb + 1; // Required to allow detection of empty and full state
+ p_fifo->pp_elements = nrf_malloc(nmemb_actual * sizeof(void *));
+
+ if (p_fifo->pp_elements == NULL)
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ else
+ {
+ p_fifo->nmemb = nmemb_actual;
+ p_fifo->wait = wait_fn;
+ p_fifo->flush = flush_fn;
+ p_fifo->read_pos = 0;
+ p_fifo->write_pos = 0;
+ }
+ return err_code;
+}
+
+void nrf_fifo_deinit(nrf_fifo_t * p_fifo)
+{
+ if (p_fifo->flush != NULL)
+ {
+ void * p_data;
+ uint32_t err_code = nrf_fifo_deq(p_fifo, &p_data, false);
+ while (err_code == NRF_SUCCESS)
+ {
+ p_fifo->flush(p_data);
+ err_code = nrf_fifo_deq(p_fifo, &p_data, false);
+ }
+ }
+ nrf_free(p_fifo->pp_elements);
+ p_fifo->nmemb = 0;
+ p_fifo->read_pos = 0;
+ p_fifo->write_pos = 0;
+ p_fifo->wait = NULL;
+ p_fifo->flush = NULL;
+}
+
+uint32_t nrf_fifo_enq(nrf_fifo_t * p_fifo, void * p_ctx, bool wait)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (fifo_full(p_fifo) == true)
+ {
+ if (wait == false || p_fifo->wait == NULL)
+ {
+ err_code = SOCKET_WOULD_BLOCK;
+ }
+ else
+ {
+ while (fifo_full(p_fifo) == true && err_code == NRF_SUCCESS)
+ {
+ err_code = p_fifo->wait();
+ }
+ }
+ }
+ else
+ {
+ fifo_enq(p_fifo, p_ctx);
+ }
+ return err_code;
+}
+
+uint32_t nrf_fifo_deq(nrf_fifo_t * p_fifo, void ** pp_ctx, bool wait)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (fifo_empty(p_fifo) == true)
+ {
+ if (wait == false || p_fifo->wait == NULL)
+ {
+ err_code = SOCKET_WOULD_BLOCK;
+ }
+ else
+ {
+ while (fifo_empty(p_fifo) == true && err_code == NRF_SUCCESS)
+ {
+ err_code = p_fifo->wait();
+ }
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ fifo_deq(p_fifo, pp_ctx);
+ }
+ return err_code;
+}
+
+bool nrf_fifo_empty(nrf_fifo_t * p_fifo)
+{
+ return fifo_empty(p_fifo);
+}
+
+bool nrf_fifo_full(nrf_fifo_t * p_fifo)
+{
+ return fifo_full(p_fifo);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.h
new file mode 100644
index 0000000..c6fb378
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.h
@@ -0,0 +1,170 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_FIFO_H__
+#define NRF_FIFO_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file nrf_fifo.h
+ *
+ * @defgroup iot_socket_fifo FIFO
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief A wait-free bounded FIFO of pointers for single producer/single consumer use.
+ *
+ * This FIFO is safe to use in single producer/single consumer patterns. In addition, the following
+ * restrictions apply for init/deinit:
+ *
+ * a) nrf_fifo_enq() and nrf_fifo_deq() may only be called after nrf_fifo_init() is called.
+ *
+ * b) All calls to nrf_fifo_enq() and nrf_fifo_deq() must be finished and no new calls must be made before nrf_fifo_deinit() is called.
+ *
+ * These restrictions must be handled by the user of the module, for instance by using a mutex.
+ */
+
+/**
+ * @brief Wait function for blocking enqueue/dequeue.
+ *
+ * Should return NRF_SUCCESS as long as there are no errors while waiting.
+ */
+typedef uint32_t (*fifo_wait_fn)(void);
+
+/**
+ * @brief Flush function called on deinit.
+ *
+ * On deinit, this function will be called with each remaining element in the FIFO as argument. This
+ * can be used to ensure that memory is deallocated properly.
+ *
+ * @param[in] p_data Pointer to data that is flushed from FIFO.
+ */
+typedef void (*fifo_flush_fn)(void * p_data);
+
+/**
+ * @brief FIFO data structure.
+ */
+typedef struct {
+ void ** pp_elements; /**< The array of elements in the FIFO. */
+ uint32_t nmemb; /**< The number of elements in this FIFO. */
+ fifo_wait_fn wait; /**< The wait function used if blocking. */
+ fifo_flush_fn flush; /**< The flush function used on deinit. */
+ volatile uint32_t read_pos; /**< Read pointer to next element to read. */
+ volatile uint32_t write_pos; /**< Write pointer to next element to write. */
+} nrf_fifo_t;
+
+/**
+ * @brief Function for initializing the FIFO.
+ *
+ * @param[out] p_fifo The FIFO to initialize.
+ * @param[in] nmemb The maximum number of elements in the FIFO.
+ * @param[in] wait_fn The wait function to use for blocking enqueue/dequeue. If NULL, the enq/deq
+ * functions will never block.
+ * @param[in] flush_fn The flush function to call on deinit. If NULL, the flush function will not
+ * be called.
+ *
+ * @retval NRF_SUCCESS if fifo was initialized successfully.
+ */
+uint32_t nrf_fifo_init(nrf_fifo_t * p_fifo, uint32_t nmemb, fifo_wait_fn wait_fn, fifo_flush_fn flush_fn);
+
+/**
+ * @brief Function for deinitializing the FIFO.
+ *
+ * Frees all memory allocated by this FIFO. All elements are removed. If a flush function was
+ * specified in nrf_fifo_init(), the function will be called for each remaining element in the
+ * FIFO.
+ *
+ * @param[in, out] p_fifo The FIFO to deinitialize.
+ */
+void nrf_fifo_deinit(nrf_fifo_t * p_fifo);
+
+/**
+ * @brief Function for enqueuing an element on the FIFO.
+ *
+ * @param[in, out] p_fifo The FIFO to enqueue elements on.
+ * @param[in] p_ctx The pointer to enqueue.
+ * @param[in] wait If true, this function will block until the FIFO has available space. Any
+ * errors returned by this function will be propagated to the caller.
+ *
+ * @retval NRF_SUCCESS if the element was queued.
+ * @retval NRF_ERROR_NO_MEM if wait was set to false and no space was available.
+ */
+uint32_t nrf_fifo_enq(nrf_fifo_t * p_fifo, void * p_ctx, bool wait);
+
+/**
+ * @brief Function for dequeuing an element from the FIFO.
+ *
+ * @param[in, out] p_fifo The FIFO to dequeue elements from.
+ * @param[out] pp_ctx Pointer to where the dequeued element should be stored.
+ * @param[in] wait If true, this function will block until the FIFO has elements for dequeuing.
+ * Any errors returned by this function will be propagated to the caller.
+ *
+ * @retval NRF_SUCCESS if the element was queued.
+ * @retval NRF_ERROR_NO_MEM if wait was set to false and no space was available.
+ */
+uint32_t nrf_fifo_deq(nrf_fifo_t * p_fifo, void ** pp_ctx, bool wait);
+
+/**
+ * @brief Function for checking if the FIFO is empty.
+ *
+ * @param[in] p_fifo The FIFO to check.
+ * @return true if empty, false if not.
+ */
+bool nrf_fifo_empty(nrf_fifo_t * p_fifo);
+
+/**
+ * @brief Function for checking if the FIFO is full.
+ *
+ * @param[in] p_fifo The FIFO to check.
+ * @return true if full, false if not.
+ */
+bool nrf_fifo_full(nrf_fifo_t * p_fifo);
+
+/**@} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_FIFO_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.c
new file mode 100644
index 0000000..d4b0c79
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.c
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "iot_defines.h"
+#include "iot_errors.h"
+#include "sdk_config.h"
+#include "mem_manager.h"
+#include "mbuf.h"
+#include "nrf_fifo.h"
+#include "socket_common.h"
+
+uint32_t mbuf_init(mbuf_t * p_mbuf,
+ mbuf_read_fn read_fn,
+ mbuf_buf_len_fn buf_len_fn,
+ mbuf_free_fn free_fn,
+ uint32_t nmemb)
+{
+ p_mbuf->p_current = NULL;
+ p_mbuf->read_pos = 0;
+ p_mbuf->read = read_fn;
+ p_mbuf->buf_len = buf_len_fn;
+ p_mbuf->free = free_fn;
+ return nrf_fifo_init(&p_mbuf->fifo, nmemb, socket_wait, free_fn);
+}
+
+void mbuf_deinit(mbuf_t * p_mbuf)
+{
+ if (p_mbuf->p_current != NULL)
+ {
+ p_mbuf->free(p_mbuf->p_current);
+ p_mbuf->p_current = NULL;
+ }
+
+ p_mbuf->read_pos = 0;
+ p_mbuf->read = NULL;
+ p_mbuf->buf_len = NULL;
+ p_mbuf->free = NULL;
+ nrf_fifo_deinit(&p_mbuf->fifo);
+}
+
+static bool mbuf_empty_current(mbuf_t * p_mbuf)
+{
+ return (p_mbuf->buf_len(p_mbuf->p_current) == p_mbuf->read_pos);
+}
+
+bool mbuf_empty(mbuf_t * p_mbuf)
+{
+ return ((p_mbuf->p_current == NULL || mbuf_empty_current(p_mbuf)) &&
+ nrf_fifo_empty(&p_mbuf->fifo));
+}
+
+uint32_t mbuf_write(mbuf_t * p_mbuf, void * p_ctx)
+{
+ return nrf_fifo_enq(&p_mbuf->fifo, p_ctx, false);
+}
+
+static void mbuf_load(mbuf_t * p_mbuf)
+{
+ if (p_mbuf->p_current == NULL)
+ {
+ (void)nrf_fifo_deq(&p_mbuf->fifo, &p_mbuf->p_current, false);
+ }
+}
+
+uint32_t mbuf_read(mbuf_t * p_mbuf, void * p_buf, uint32_t buf_size)
+{
+ uint32_t nbytes = 0;
+ while (nbytes < buf_size && mbuf_empty(p_mbuf) == false)
+ {
+ mbuf_load(p_mbuf);
+ void * p_current = p_mbuf->p_current;
+ const uint32_t copy_len = p_mbuf->read(p_current,
+ p_mbuf->read_pos,
+ ((uint8_t *)p_buf) + nbytes,
+ buf_size - nbytes);
+ p_mbuf->read_pos += copy_len;
+ nbytes += copy_len;
+ if (mbuf_empty_current(p_mbuf) == true)
+ {
+ p_mbuf->free(p_mbuf->p_current);
+ p_mbuf->p_current = NULL;
+ p_mbuf->read_pos = 0;
+ }
+ }
+ return nbytes;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.h
new file mode 100644
index 0000000..884c650
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.h
@@ -0,0 +1,146 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef MBUF_H__
+#define MBUF_H__
+
+/**
+ * @file mbuf.h
+ *
+ * @defgroup iot_socket_mbuf Memory management for socket
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Memory management for socket.
+ */
+
+#include <stdbool.h>
+#include "nrf_fifo.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for reading data from a buffer. */
+typedef uint32_t (*mbuf_read_fn)(void * p_ctx,
+ uint32_t read_offset,
+ uint8_t * p_dest,
+ uint32_t dest_len);
+
+/**@brief Function for checking buffer length. */
+typedef uint32_t (*mbuf_buf_len_fn)(void * p_ctx);
+
+/**@brief Function for freeing a buffer. */
+typedef void (*mbuf_free_fn)(void * p_ctx);
+
+/**@brief Memory management structure. */
+typedef struct
+{
+ nrf_fifo_t fifo; /**< FIFO for storing data buffers. */
+ mbuf_read_fn read; /**< Function for reading data from a buffer. */
+ mbuf_buf_len_fn buf_len; /**< Function for checking buffer length. */
+ mbuf_free_fn free; /**< Function for freeing a buffer. */
+ uint32_t read_pos; /**< Read position in the currently processed buffer. */
+ void * p_current; /**< Pointer to the currently processed buffer. */
+} mbuf_t;
+
+/**
+ * @brief Function for initializing the memory buffer manager.
+ *
+ * This function allocates resources for the mbuf FIFO and initializes the mbuf.
+ *
+ * @param[in, out] p_mbuf Pointer to the mbuf structure to initialize.
+ * @param[in] read_fn Function for reading data from a buffer.
+ * @param[in] buf_len_fn Function for checking buffer length.
+ * @param[in] free_fn Function for freeing a buffer.
+ * @param[in] nmemb Maximum number of data buffers.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code is returned.
+ */
+uint32_t mbuf_init(mbuf_t * p_mbuf,
+ mbuf_read_fn read_fn,
+ mbuf_buf_len_fn buf_len_fn,
+ mbuf_free_fn free_fn,
+ uint32_t nmemb);
+
+/**
+ * @brief Function for deinitializing the memory buffer manager.
+ *
+ * This function releases any resources allocated for mbuf instance pointed by p_mbuf.
+ *
+ * @param[in, out] p_mbuf Pointer to the mbuf structure to deinitialize.
+ */
+void mbuf_deinit(mbuf_t * p_mbuf);
+
+/**
+ * @brief Function for putting a data buffer in the mbuf.
+ *
+ * @param[in, out] p_mbuf Pointer to the mbuf structure that shall store the buffer.
+ * @param[in] p_ctx Pointer to the data buffer to store.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code is returned.
+ */
+uint32_t mbuf_write(mbuf_t * p_mbuf, void * p_ctx);
+
+/**
+ * @brief Function for reading data from the mbuf.
+ *
+ * @param[in, out] p_mbuf Pointer to the mbuf structure to read data from.
+ * @param[in] p_buf Pointer to the buffer where data shall be read from.
+ * @param[out] buf_size Size of the buffer pointed by p_buf.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code is returned.
+ */
+uint32_t mbuf_read(mbuf_t * p_mbuf, void * p_buf, uint32_t buf_size);
+
+/**
+ * @brief Function for checking if the mbuf is empty.
+ *
+ * @param[in] p_mbuf Pointer to the mbuf structure that shall be checked.
+ *
+ * @return True if mbuf is empty, false otherwise.
+ */
+bool mbuf_empty(mbuf_t * p_mbuf);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // MBUF_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.c
new file mode 100644
index 0000000..7bfbcc4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.c
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "portdb.h"
+#include <string.h>
+#include "iot_common.h"
+#include "iot_errors.h"
+#include "mem_manager.h"
+#include "nrf_error.h"
+
+#define IANA_EPHEMRAL_BEGIN 49152u /**< Minimum port number of the ephemeral port range. */
+#define IANA_EPHEMRAL_END 65535u /**< Maximum port number of the ephemeral port range. */
+
+static uint16_t * m_portdb; /**< A pointer to the port database. */
+static uint32_t m_portdb_len; /**< Length of the port database. */
+
+
+
+static __INLINE uint32_t db_size_get(void)
+{
+ return m_portdb_len * sizeof(uint16_t);
+}
+
+
+static __INLINE void db_reset(void)
+{
+ memset(&m_portdb[0], 0, db_size_get());
+}
+
+
+uint32_t portdb_init(uint32_t max_ports)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ m_portdb_len = max_ports;
+ m_portdb = nrf_malloc(db_size_get());
+ if (m_portdb == NULL)
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ else
+ {
+ db_reset();
+ }
+ return err_code;
+}
+
+
+void portdb_deinit(void)
+{
+ nrf_free(m_portdb);
+ m_portdb = NULL;
+ m_portdb_len = 0;
+}
+
+
+void portdb_reset(void)
+{
+ db_reset();
+}
+
+
+static inline uint32_t check_port_in_use(uint16_t port)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ for (uint32_t i = 0; i < m_portdb_len; i++)
+ {
+ if (m_portdb[i] == port)
+ {
+ err_code = SOCKET_PORT_IN_USE;
+ break;
+ }
+ }
+ return err_code;
+}
+
+static inline uint32_t find_free_index(uint32_t * p_idx)
+{
+ uint32_t err_code = SOCKET_NO_AVAILABLE_PORTS;
+
+ for (uint32_t i = 0; i < m_portdb_len; i++)
+ {
+ if (m_portdb[i] == 0)
+ {
+ *p_idx = i;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+ return err_code;
+}
+
+static uint32_t portdb_find_available_index(uint32_t * p_idx, uint16_t port)
+{
+ uint32_t err_code = SOCKET_NO_AVAILABLE_PORTS;
+
+ err_code = check_port_in_use(port);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = find_free_index(p_idx);
+ }
+ return err_code;
+}
+
+uint32_t portdb_register(uint16_t port)
+{
+ uint32_t idx = 0;
+ uint32_t err_code = portdb_find_available_index(&idx, port);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_portdb[idx] = port;
+ }
+ return err_code;
+}
+
+uint32_t portdb_alloc(uint16_t * p_port)
+{
+ uint32_t err_code = SOCKET_NO_AVAILABLE_PORTS;
+ for (uint32_t i = IANA_EPHEMRAL_BEGIN; i <= IANA_EPHEMRAL_END; i++)
+ {
+ uint16_t port = (uint16_t)i;
+ err_code = portdb_register(port);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ *p_port = port;
+ break;
+ }
+ else if (err_code == SOCKET_NO_AVAILABLE_PORTS)
+ {
+ break;
+ }
+ }
+ return err_code;
+}
+
+void portdb_free(uint16_t port)
+{
+ for (uint32_t i = 0; i < m_portdb_len; i++)
+ {
+ if (m_portdb[i] == port)
+ {
+ m_portdb[i] = 0;
+ break;
+ }
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.h
new file mode 100644
index 0000000..94f0d38
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.h
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef PORTDB_H__
+#define PORTDB_H__
+
+/**
+ * @file portdb.h
+ *
+ * @defgroup iot_socket_portdb Port Database
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Port database for sockets.
+ *
+ * The port database provides a functionality for registering, allocating, and freeing ports.
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for initializing the port database.
+ *
+ * This must be called before allocating and freeing ports.
+ *
+ * @param max_len The max length of the portdb.
+ *
+ * @retval NRF_SUCCESS If successfully initialized.
+ */
+uint32_t portdb_init(uint32_t max_len);
+
+/**
+ * @brief Function for deinitializing the portdb.
+ *
+ * This will free all memory allocated by this portdb.
+ */
+void portdb_deinit(void);
+
+/**
+ * @brief Function to reset all ports without freeing any memories.
+ */
+void portdb_reset(void);
+
+/**
+ * @brief Function for allocating a port.
+ *
+ * Looks for an available port in the database and allocates it to the caller.
+ *
+ * @param[out] p_port Pointer to a variable where the allocated port number should be stored.
+ *
+ * @retval NRF_SUCCESS If a free port was located and successfully allocated.
+ * @retval SOCKET_NO_AVAILABLE_PORTS If no available ports were found.
+ */
+uint32_t portdb_alloc(uint16_t * p_port);
+
+/**
+ * @brief Function for registering a port.
+ *
+ * Marks a given port in the database as being in use.
+ *
+ * @param[in] port The port to mark as in use.
+ *
+ * @retval NRF_SUCCESS If port was successfully marked as in use.
+ * @retval SOCKET_NO_AVAILABLE_PORTS If there was no slot in which to register the port.
+ * @retval SOCKET_PORT_IN_USE If the port has already been registered or allocated.
+ */
+uint32_t portdb_register(uint16_t port);
+
+/**
+ * @brief Function for freeing a port.
+ *
+ * Mark a given port as free and make it available for others to register or allocate.
+ *
+ * @param[in] port The port to mark as free.
+ */
+void portdb_free(uint16_t port);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // PORTDB_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/platform/ble/socket_ble.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/platform/ble/socket_ble.c
new file mode 100644
index 0000000..da2cc7b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/platform/ble/socket_ble.c
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <stdint.h>
+#include "nrf_soc.h"
+#include "app_scheduler.h"
+
+uint32_t socket_wait(void)
+{
+ // Execute event schedule.
+ app_sched_execute();
+
+ return sd_app_evt_wait();
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/ipv6/transport_handler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/ipv6/transport_handler.c
new file mode 100644
index 0000000..a9d6edd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/ipv6/transport_handler.c
@@ -0,0 +1,387 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "iot_defines.h"
+#include "iot_errors.h"
+#include "sdk_config.h"
+#include "socket_trace.h"
+#include "socket_common.h"
+#include "socket_config.h"
+#include "config_medium.h"
+#include "transport_if.h"
+#include "udp_api.h"
+#include "portdb.h"
+#include "nrf_soc.h"
+#include "nrf_fifo.h"
+
+/**@brief Verify that IPv6 address length is correct. */
+#define VERIFY_ADDRESS_LEN(len) \
+ do { \
+ if ((len) != sizeof(sockaddr_in6_t)) { \
+ return NRF_ERROR_NULL | IOT_SOCKET_ERR_BASE; \
+ } \
+ } while (0)
+
+#define SOCKET_MAX_PENDING_PACKETS 32 /**< Maximum number of pending received packets. */
+
+/**@brief Nordic IPv6 handle structure. */
+typedef struct
+{
+ udp6_socket_t socket; /**< UDP socket. */
+ nrf_fifo_t recv_queue; /**< Received packets queue. */
+ uint16_t local_port; /**< Local port number. */
+} ipv6_handle_t;
+
+static const char * unused = "UNUSED"; /**< A pointer indicating an unused socket. */
+static ipv6_handle_t ipv6_handles[SOCKET_MAX_SOCKET_COUNT]; /**< IPv6 handle array. */
+
+void free_pbuffer(void * p_data)
+{
+ (void) iot_pbuffer_free((iot_pbuffer_t *)p_data, true);
+}
+
+static ipv6_handle_t * ipv6_handle_allocate(socket_t * p_socket)
+{
+ ipv6_handle_t * p_handle = NULL;
+ for (uint32_t i = 0; i < SOCKET_MAX_SOCKET_COUNT; i++)
+ {
+ if (ipv6_handles[i].socket.p_app_data == unused)
+ {
+ p_handle = &ipv6_handles[i];
+ p_handle->socket.p_app_data = p_socket;
+ (void) nrf_fifo_init(&p_handle->recv_queue, SOCKET_MAX_PENDING_PACKETS, socket_wait, free_pbuffer);
+ uint32_t err_code = udp6_socket_app_data_set(&p_handle->socket);
+ if (err_code != NRF_SUCCESS)
+ {
+ p_handle = NULL;
+ }
+ break;
+ }
+ }
+ return p_handle;
+}
+
+static uint32_t ipv6_handle_free(ipv6_handle_t * p_handle)
+{
+ p_handle->local_port = 0;
+ p_handle->socket.p_app_data = (void *)unused;
+ return udp6_socket_app_data_set(&p_handle->socket);
+}
+
+void transport_event_handler(iot_interface_t * p_interface, ipv6_event_t * p_event)
+{
+ (void) p_interface;
+
+ switch (p_event->event_id)
+ {
+ case IPV6_EVT_INTERFACE_ADD:
+ transport_interface_up();
+ break;
+ case IPV6_EVT_INTERFACE_DELETE:
+ transport_interface_down();
+ break;
+ case IPV6_EVT_INTERFACE_RX_DATA:
+ break;
+ default:
+ break;
+ }
+}
+
+void transport_handler_init(void)
+{
+ ipv6_init_t init_param;
+ init_param.p_eui64 = config_medium_local_iid();
+ init_param.event_handler = transport_event_handler;
+
+ uint32_t err_code = ipv6_init(&init_param);
+ (void) err_code;
+ // APP_ERROR_CHECK(err_code);
+ for (uint32_t i = 0; i< SOCKET_MAX_SOCKET_COUNT; i++)
+ {
+ ipv6_handles[i].local_port = 0;
+ ipv6_handles[i].socket.socket_id = 0;
+ ipv6_handles[i].socket.p_app_data = (void *)unused;
+ }
+}
+
+static uint32_t ipv6_transport_open(socket_t * p_socket)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ if (p_socket->so_params.so_type != SOCK_DGRAM)
+ {
+ err_code = SOCKET_UNSUPPORTED_PROTOCOL;
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ ipv6_handle_t * p_ipv6_handle = ipv6_handle_allocate(p_socket);
+ if (p_ipv6_handle == NULL)
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+ else
+ {
+ err_code = udp6_socket_allocate(&p_ipv6_handle->socket);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_socket->so_ctx = p_ipv6_handle;
+ }
+ else
+ {
+ (void) ipv6_handle_free(p_ipv6_handle);
+ }
+ }
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_close(socket_t * p_socket)
+{
+ ipv6_handle_t * p_ipv6_handle = (ipv6_handle_t *) p_socket->so_ctx;
+ if (p_ipv6_handle->local_port > 0)
+ {
+ portdb_free(p_ipv6_handle->local_port);
+ }
+
+ uint32_t err_code = udp6_socket_free(&p_ipv6_handle->socket);
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = ipv6_handle_free(p_ipv6_handle);
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_recv_callback(const udp6_socket_t * p_udp_socket,
+ const ipv6_header_t * p_ip_header,
+ const udp6_header_t * p_udp_header,
+ uint32_t process_result,
+ iot_pbuffer_t * p_rx_packet)
+{
+ uint32_t err_code = process_result;
+ socket_t * p_socket = (socket_t *)p_udp_socket->p_app_data;
+ ipv6_handle_t * p_ipv6_handle = (ipv6_handle_t *)p_socket->so_ctx;
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = nrf_fifo_enq(&p_ipv6_handle->recv_queue, p_rx_packet, false);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_socket->so_read_evt++;
+ err_code = IOT_IPV6_ERR_PENDING;
+ }
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_bind(socket_t * p_socket, const void * p_addr, socklen_t addr_len)
+{
+ VERIFY_ADDRESS_LEN(addr_len);
+ const sockaddr_in6_t * p_addr_in6 = (const sockaddr_in6_t *)p_addr;
+ ipv6_handle_t * p_ipv6_handle = (ipv6_handle_t *)p_socket->so_ctx;
+ udp6_socket_t * p_udp_socket = &p_ipv6_handle->socket;
+
+ p_ipv6_handle->local_port = HTONS(p_addr_in6->sin6_port);
+ uint32_t err_code = portdb_register(p_ipv6_handle->local_port);
+ if (err_code == NRF_SUCCESS)
+ {
+ ipv6_addr_t * p_ipv6_addr = (ipv6_addr_t *)&p_addr_in6->sin6_addr;
+ err_code = udp6_socket_bind(p_udp_socket, p_ipv6_addr, p_ipv6_handle->local_port);
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = udp6_socket_recv(p_udp_socket, ipv6_transport_recv_callback);
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_bind_any(ipv6_handle_t * p_ipv6_handle)
+{
+ udp6_socket_t * p_udp_socket = &p_ipv6_handle->socket;
+ uint32_t err_code = portdb_alloc(&p_ipv6_handle->local_port);
+ if (err_code == NRF_SUCCESS)
+ {
+ SOCKET_TRACE("Binding to port %hu\r\n", p_ipv6_handle->local_port);
+ err_code = udp6_socket_bind(p_udp_socket, IPV6_ADDR_ANY, p_ipv6_handle->local_port);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = udp6_socket_recv(p_udp_socket, ipv6_transport_recv_callback);
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_connect(socket_t * p_socket, const void * p_addr, socklen_t addr_len)
+{
+ VERIFY_ADDRESS_LEN(addr_len);
+
+ ipv6_handle_t * p_ipv6_handle = (ipv6_handle_t *)p_socket->so_ctx;
+ udp6_socket_t * p_udp_socket = &p_ipv6_handle->socket;
+ const sockaddr_in6_t * p_addr_in6 = (const sockaddr_in6_t *)p_addr;
+ uint32_t err_code = NRF_SUCCESS;
+
+ // Port might already have been bound with an explicit call to bind()
+ if (p_ipv6_handle->local_port == 0)
+ {
+ err_code = ipv6_transport_bind_any(p_ipv6_handle);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // These data structures are compatible, and can therefore be cast
+ err_code = udp6_socket_connect(p_udp_socket,
+ (ipv6_addr_t *)&p_addr_in6->sin6_addr,
+ HTONS(p_addr_in6->sin6_port));
+ }
+
+ return err_code;
+}
+
+static uint32_t ipv6_transport_send(socket_t * p_socket,
+ const void * p_buf,
+ uint32_t len,
+ int flags,
+ const void * p_destaddr,
+ socklen_t destaddr_len)
+{
+ ipv6_handle_t * p_ipv6_handle = (ipv6_handle_t *)p_socket->so_ctx;
+ udp6_socket_t * p_udp_socket = &p_ipv6_handle->socket;
+ uint32_t err_code = NRF_SUCCESS;
+ iot_pbuffer_alloc_param_t pbuff_param;
+
+ // Ensure that port is bound before sending packet
+ if (p_ipv6_handle->local_port == 0)
+ {
+ err_code = ipv6_transport_bind_any(p_ipv6_handle);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ pbuff_param.flags = PBUFFER_FLAG_DEFAULT;
+ pbuff_param.type = UDP6_PACKET_TYPE;
+ pbuff_param.length = len;
+
+ iot_pbuffer_t * p_buffer = NULL;
+ err_code = iot_pbuffer_allocate(&pbuff_param, &p_buffer);
+ if (err_code == NRF_SUCCESS)
+ {
+ memcpy(p_buffer->p_payload, p_buf, len);
+ if (p_destaddr != NULL && destaddr_len == sizeof(sockaddr_in6_t))
+ {
+ sockaddr_in6_t * p_addr_in6 = (sockaddr_in6_t *)p_destaddr;
+ err_code = udp6_socket_sendto(p_udp_socket,
+ (ipv6_addr_t *)&p_addr_in6->sin6_addr,
+ HTONS(p_addr_in6->sin6_port),
+ p_buffer);
+ }
+ else
+ {
+ err_code = udp6_socket_send(p_udp_socket, p_buffer);
+ }
+ }
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_recv(socket_t * p_socket,
+ void * p_buf,
+ uint32_t * p_sz,
+ int flags,
+ void * p_srcaddr,
+ socklen_t * p_srcaddr_len)
+{
+ if ((p_socket->so_flags & O_NONBLOCK) != 0 &&
+ (flags & MSG_WAITALL) == 0)
+ {
+ flags |= MSG_DONTWAIT;
+ }
+
+ ipv6_handle_t * p_ipv6_handle = (ipv6_handle_t *)p_socket->so_ctx;
+ iot_pbuffer_t * p_pbuffer = NULL;
+ uint32_t err_code = nrf_fifo_deq(&p_ipv6_handle->recv_queue,
+ (void **)&p_pbuffer,
+ (flags & MSG_DONTWAIT) == 0);
+ if (err_code == NRF_SUCCESS)
+ {
+ uint32_t copy_len = MIN(*p_sz, p_pbuffer->length);
+ memcpy(p_buf, p_pbuffer->p_payload, copy_len);
+ *p_sz = copy_len;
+
+ if (p_srcaddr != NULL && p_srcaddr_len != NULL)
+ {
+ const udp6_header_t * p_udp_header =
+ (udp6_header_t *)(p_pbuffer->p_payload - UDP_HEADER_SIZE);
+ const ipv6_header_t * p_ipv6_header =
+ (ipv6_header_t *)(p_pbuffer->p_payload - UDP_HEADER_SIZE - IPV6_IP_HEADER_SIZE);
+ sockaddr_in6_t * p_srcsockaddr = (sockaddr_in6_t *)p_srcaddr;
+
+ *p_srcaddr_len = sizeof(sockaddr_in6_t);
+ p_srcsockaddr->sin6_addr = *((in6_addr_t *)&p_ipv6_header->srcaddr);
+ p_srcsockaddr->sin6_port = HTONS(p_udp_header->srcport);
+ p_srcsockaddr->sin6_len = *p_srcaddr_len;
+ p_srcsockaddr->sin6_family = AF_INET6;
+ p_srcsockaddr->sin6_flowinfo = 0;
+ p_srcsockaddr->sin6_scope_id = 0;
+ }
+
+ (void) iot_pbuffer_free(p_pbuffer, true);
+ p_socket->so_read_evt = 0;
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_listen(socket_t * p_socket, int backlog)
+{
+ // Ignore as this does not make sense for UDP
+ (void) p_socket;
+ (void) backlog;
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Transport for Nordic IPv6 socket.
+ */
+socket_transport_t transport_impl =
+{
+ .open = ipv6_transport_open,
+ .bind = ipv6_transport_bind,
+ .connect = ipv6_transport_connect,
+ .send = ipv6_transport_send,
+ .recv = ipv6_transport_recv,
+ .listen = ipv6_transport_listen,
+ .close = ipv6_transport_close
+};
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/lwip/transport_handler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/lwip/transport_handler.c
new file mode 100644
index 0000000..4537053
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/lwip/transport_handler.c
@@ -0,0 +1,630 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "iot_defines.h"
+#include "iot_errors.h"
+#include "sdk_config.h"
+#include "socket_common.h"
+#include "socket_trace.h"
+#include "transport_if.h"
+#include "portdb.h"
+#include "app_timer.h"
+#include "mem_manager.h"
+#include "nrf_fifo.h"
+#include "mbuf.h"
+#include "app_util.h"
+#include "nrf_platform_port.h"
+#include "app_util_platform.h"
+
+#include "lwip/opt.h"
+#include "lwip/init.h"
+#include "lwip/tcp.h"
+#include "lwip/timers.h"
+
+/**@brief Verify that IPv6 address length is correct. */
+#define VERIFY_ADDRESS_LEN(len) \
+ do { \
+ if ((len) != sizeof(sockaddr_in6_t)) { \
+ return NRF_ERROR_NULL | IOT_SOCKET_ERR_BASE; \
+ } \
+ } while (0)
+
+#define LWIP_SYS_TIMER_INTERVAL APP_TIMER_TICKS(100) /**< Interval for timer used as trigger to send. */
+
+#define SOCKET_MAX_PENDING_PACKETS 32 /**< Maximum number of pending received packets. */
+#define SOCKET_MAX_PENDING_CONNECTIONS 10 /**< Maximum number of simultaneous connections. */
+
+/**@brief TCP state */
+typedef enum
+{
+ TCP_STATE_IDLE,
+ TCP_STATE_REQUEST_CONNECTION,
+ TCP_STATE_CONNECTED,
+ TCP_STATE_DATA_TX_IN_PROGRESS,
+ TCP_STATE_TCP_SEND_PENDING,
+ TCP_STATE_DISCONNECTED
+} tcp_state_t;
+
+/**@brief LwIP handle structure. */
+typedef struct {
+ struct tcp_pcb * p_pcb; /**< A pointer to LwIP TCP protocol control block. */
+ socket_t * p_socket; /**< A pointer to corresponding socket. */
+ nrf_fifo_t conn_queue; /**< Connections queue. */
+ mbuf_t mbuf; /**< Memory management queue. */
+ volatile tcp_state_t tcp_state; /**< TCP state. */
+} lwip_handle_t;
+
+static lwip_handle_t lwip_handles[SOCKET_MAX_SOCKET_COUNT]; /**< LwIP handle array. */
+
+/**@brief Timer for LwIP. */
+APP_TIMER_DEF(m_lwip_timer_id);
+
+static err_t lwip_recv_callback(void * p_arg,
+ struct tcp_pcb * p_pcb,
+ struct pbuf * p_pbuf,
+ err_t err);
+
+static uint32_t lwip_buf_read(void * p_ctx,
+ uint32_t read_offset,
+ uint8_t * p_destbuf,
+ uint32_t destbuf_len)
+{
+ struct pbuf * p_pbuf = (struct pbuf *)p_ctx;
+ uint32_t copy_len = MIN(destbuf_len, (p_pbuf->len - read_offset));
+ memcpy(p_destbuf, (void *)(((uint8_t *)p_pbuf->payload) + read_offset), copy_len);
+ return copy_len;
+}
+
+static uint32_t lwip_buf_len(void * p_ctx)
+{
+ struct pbuf * p_pbuf = (struct pbuf *)p_ctx;
+ return p_pbuf->len;
+}
+
+static void lwip_buf_free(void * p_ctx)
+{
+ nrf_free(((struct pbuf *)p_ctx)->payload);
+ (void) pbuf_free((struct pbuf *)p_ctx);
+}
+
+static void lwip_timer_callback(void * p_ctx)
+{
+ (void) p_ctx;
+ sys_check_timeouts();
+}
+
+void nrf_driver_interface_up(iot_interface_t const * p_interface)
+{
+ UNUSED_PARAMETER(p_interface);
+ transport_interface_up();
+}
+
+void nrf_driver_interface_down(iot_interface_t const * p_interface)
+{
+ UNUSED_PARAMETER(p_interface);
+ transport_interface_down();
+}
+
+void transport_handler_init(void)
+{
+ lwip_init();
+ uint32_t err_code = nrf_driver_init();
+ APP_ERROR_CHECK(err_code);
+ for (uint32_t i = 0; i < SOCKET_MAX_SOCKET_COUNT; i++)
+ {
+ lwip_handles[i].p_pcb = NULL;
+ lwip_handles[i].p_socket = NULL;
+ lwip_handles[i].tcp_state = TCP_STATE_IDLE;
+ }
+ err_code = app_timer_create(&m_lwip_timer_id,
+ APP_TIMER_MODE_REPEATED,
+ lwip_timer_callback);
+ APP_ERROR_CHECK(err_code);
+ err_code = app_timer_start(m_lwip_timer_id, LWIP_SYS_TIMER_INTERVAL, NULL);
+ APP_ERROR_CHECK(err_code);
+ SOCKET_TRACE("Initialized LWIP transport handler\r\n");
+}
+
+static void lwip_error_handler(void * p_arg, err_t err)
+{
+ (void) p_arg;
+ SOCKET_TRACE("Error occured: %d\r\n", (int)err);
+ if(err == ERR_ABRT)
+ {
+ portdb_reset();
+ }
+}
+
+static err_t lwip_poll_handler(void * p_arg, struct tcp_pcb * p_pcb)
+{
+ (void) p_arg;
+ (void) p_pcb;
+
+ return ERR_OK;
+}
+
+static void lwip_drop_connection(void * p_ctx)
+{
+ struct tcp_pcb * p_pcb = (struct tcp_pcb *)p_ctx;
+ tcp_abort(p_pcb);
+}
+
+static lwip_handle_t * lwip_handle_allocate(socket_t * p_socket, struct tcp_pcb * p_pcb)
+{
+ lwip_handle_t * p_handle = NULL;
+ for (uint32_t i = 0; i < SOCKET_MAX_SOCKET_COUNT; i++)
+ {
+ if (lwip_handles[i].p_pcb == NULL)
+ {
+ p_handle = &lwip_handles[i];
+ (void)mbuf_init(&p_handle->mbuf,
+ lwip_buf_read,
+ lwip_buf_len,
+ lwip_buf_free,
+ SOCKET_MAX_PENDING_PACKETS);
+ (void) nrf_fifo_init(&p_handle->conn_queue,
+ SOCKET_MAX_PENDING_CONNECTIONS,
+ socket_wait,
+ lwip_drop_connection);
+ p_handle->p_socket = p_socket;
+ p_handle->tcp_state = TCP_STATE_IDLE;
+ if (p_pcb == NULL)
+ {
+ p_handle->p_pcb = tcp_new();
+ }
+ else
+ {
+ p_handle->p_pcb = p_pcb;
+ }
+ tcp_arg(p_handle->p_pcb, p_handle);
+ tcp_setprio(p_handle->p_pcb, TCP_PRIO_MIN);
+ tcp_recv(p_handle->p_pcb, lwip_recv_callback);
+ tcp_err(p_handle->p_pcb, lwip_error_handler);
+ tcp_poll(p_handle->p_pcb, lwip_poll_handler, 0);
+ break;
+ }
+ }
+ SOCKET_TRACE("Allocated LWIP socket handle\r\n");
+ return p_handle;
+}
+
+static void lwip_handle_free(lwip_handle_t * p_handle)
+{
+ nrf_fifo_deinit(&p_handle->conn_queue);
+ mbuf_deinit(&p_handle->mbuf);
+ p_handle->p_pcb = NULL;
+ p_handle->p_socket = NULL;
+ p_handle->tcp_state = TCP_STATE_IDLE;
+ SOCKET_TRACE("Released LWIP socket handle\r\n");
+}
+
+static uint32_t lwip_transport_open(socket_t * p_socket)
+{
+ lwip_handle_t * p_handle = NULL;
+ uint32_t err_code = NRF_SUCCESS;
+ switch (p_socket->so_params.so_type)
+ {
+ case SOCK_STREAM:
+ p_handle = lwip_handle_allocate(p_socket, NULL);
+ if (p_handle == NULL)
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+ else
+ {
+ p_socket->so_ctx = p_handle;
+ }
+ break;
+ default:
+ err_code = NRF_ERROR_NULL;
+ break;
+ }
+ return err_code;
+}
+
+uint32_t lwip_error_convert(err_t lwip_err)
+{
+ uint32_t err_code = NRF_ERROR_NULL;
+ switch (lwip_err)
+ {
+ case ERR_OK:
+ err_code = NRF_SUCCESS;
+ break;
+ case ERR_MEM:
+ err_code = SOCKET_NO_MEM;
+ break;
+ case ERR_TIMEOUT:
+ err_code = SOCKET_TIMEOUT;
+ break;
+ case ERR_RTE:
+ err_code = SOCKET_NO_ROUTE;
+ break;
+ default:
+ err_code = NRF_ERROR_NULL;
+ break;
+ }
+ return err_code;
+}
+
+static uint32_t lwip_transport_close(socket_t * p_socket)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_socket->so_ctx;
+ portdb_free((uint16_t)p_handle->p_pcb->local_port);
+ err_t err_code = tcp_close(p_handle->p_pcb);
+ if (err_code == ERR_OK)
+ {
+ lwip_handle_free(p_handle);
+ }
+ return lwip_error_convert(err_code);
+}
+
+static err_t lwip_connect_callback(void * p_arg, struct tcp_pcb * p_pcb, err_t err)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_arg;
+ // TODO: Error check
+ SOCKET_TRACE("New connection\r\n");
+ p_handle->tcp_state = TCP_STATE_CONNECTED;
+ return ERR_OK;
+}
+
+static err_t lwip_recv_callback(void * p_arg,
+ struct tcp_pcb * p_pcb,
+ struct pbuf * p_pbuf,
+ err_t err)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_arg;
+ socket_t * p_socket = p_handle->p_socket;
+ if (err == ERR_OK)
+ {
+ uint8_t * p_payload_cp = nrf_malloc(p_pbuf->len);
+ struct pbuf * p_pbuf_cp = pbuf_alloc(PBUF_RAW, p_pbuf->len, PBUF_REF);
+
+ memcpy(p_payload_cp, p_pbuf->payload, p_pbuf->len);
+ p_pbuf_cp->payload = p_payload_cp;
+ p_pbuf_cp->len = p_pbuf->len;
+ p_pbuf_cp->tot_len = p_pbuf->tot_len;
+
+ uint32_t err_code = mbuf_write(&p_handle->mbuf, p_pbuf_cp);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_socket->so_read_evt++;
+ }
+ else
+ {
+ err = ERR_MEM;
+ }
+ }
+ return err;
+}
+
+static uint32_t lwip_wait_for_state(lwip_handle_t * p_handle, tcp_state_t state)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ while (err_code == NRF_SUCCESS &&
+ p_handle->tcp_state != state &&
+ p_handle->tcp_state != TCP_STATE_DISCONNECTED)
+ {
+ err_code = socket_wait();
+ }
+ if (err_code == NRF_SUCCESS && p_handle->tcp_state != state)
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+ return err_code;
+}
+
+static void lwipaddr_to_sockaddr(const ip6_addr_t * p_lwip_addr, sockaddr_in6_t * p_addr_in6)
+{
+ struct in6_addr * addr = &p_addr_in6->sin6_addr;
+ addr->s6_addr[0] = p_lwip_addr->addr[0] & 0xFF;
+ addr->s6_addr[1] = (p_lwip_addr->addr[0] >> 8) & 0xFF;
+ addr->s6_addr[2] = (p_lwip_addr->addr[0] >> 16) & 0xFF;
+ addr->s6_addr[3] = (p_lwip_addr->addr[0] >> 24) & 0xFF;
+
+ addr->s6_addr[4] = p_lwip_addr->addr[1] & 0xFF;
+ addr->s6_addr[5] = (p_lwip_addr->addr[1] >> 8) & 0xFF;
+ addr->s6_addr[6] = (p_lwip_addr->addr[1] >> 16) & 0xFF;
+ addr->s6_addr[7] = (p_lwip_addr->addr[1] >> 24) & 0xFF;
+
+ addr->s6_addr[8] = p_lwip_addr->addr[2] & 0xFF;
+ addr->s6_addr[9] = (p_lwip_addr->addr[2] >> 8) & 0xFF;
+ addr->s6_addr[10] = (p_lwip_addr->addr[2] >> 16) & 0xFF;
+ addr->s6_addr[11] = (p_lwip_addr->addr[2] >> 24) & 0xFF;
+
+ addr->s6_addr[12] = p_lwip_addr->addr[3] & 0xFF;
+ addr->s6_addr[13] = (p_lwip_addr->addr[3] >> 8) & 0xFF;
+ addr->s6_addr[14] = (p_lwip_addr->addr[3] >> 16) & 0xFF;
+ addr->s6_addr[15] = (p_lwip_addr->addr[3] >> 24) & 0xFF;
+}
+
+static void sockaddr_to_lwipaddr(const sockaddr_in6_t * p_addr_in6, ip6_addr_t * p_lwip_addr)
+{
+ const struct in6_addr * addr = &p_addr_in6->sin6_addr;
+ IP6_ADDR_PART(p_lwip_addr, 0, addr->s6_addr[0], addr->s6_addr[1], addr->s6_addr[2], addr->s6_addr[3]);
+ IP6_ADDR_PART(p_lwip_addr, 1, addr->s6_addr[4], addr->s6_addr[5], addr->s6_addr[6], addr->s6_addr[7]);
+ IP6_ADDR_PART(p_lwip_addr, 2, addr->s6_addr[8], addr->s6_addr[9], addr->s6_addr[10], addr->s6_addr[11]);
+ IP6_ADDR_PART(p_lwip_addr, 3, addr->s6_addr[12], addr->s6_addr[13], addr->s6_addr[14], addr->s6_addr[15]);
+}
+
+static uint32_t lwip_transport_bind(socket_t * p_socket, const void * p_addr, socklen_t addr_len)
+{
+ VERIFY_ADDRESS_LEN(addr_len);
+ const sockaddr_in6_t * p_addr_in6 = (const sockaddr_in6_t *)p_addr;
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_socket->so_ctx;
+
+ uint16_t port = HTONS(p_addr_in6->sin6_port);
+ uint32_t err_code = portdb_register(port);
+ if (err_code == NRF_SUCCESS)
+ {
+ ip6_addr_t lwip_addr;
+ sockaddr_to_lwipaddr(p_addr_in6, &lwip_addr);
+ err_t err = tcp_bind(p_handle->p_pcb, &lwip_addr, port);
+ err_code = lwip_error_convert(err);
+ }
+ return err_code;
+}
+
+static uint32_t lwip_transport_connect(socket_t * p_socket,
+ const void * p_addr,
+ socklen_t addr_len)
+{
+ VERIFY_ADDRESS_LEN(addr_len);
+
+ bool is_blocking = ((p_socket->so_flags & O_NONBLOCK) == 0);
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_socket->so_ctx;
+ const sockaddr_in6_t * p_addr_in6 = (const sockaddr_in6_t *)p_addr;
+ uint16_t port = 0;
+ uint32_t err_code = portdb_alloc(&port);
+
+ SOCKET_TRACE("Binding to port %d\r\n", (int)port);
+ if (err_code == NRF_SUCCESS)
+ {
+ ip6_addr_t any_addr;
+ ip6_addr_set_any(&any_addr);
+ err_t err = tcp_bind (p_handle->p_pcb, &any_addr, port);
+ SOCKET_TRACE("Err %d from bind\r\n", (int)err);
+ err_code = lwip_error_convert(err);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ ip6_addr_t remote_addr;
+ sockaddr_to_lwipaddr(p_addr_in6, &remote_addr);
+
+ p_handle->tcp_state = TCP_STATE_REQUEST_CONNECTION;
+ err_t err = tcp_connect(p_handle->p_pcb, &remote_addr, HTONS(p_addr_in6->sin6_port), lwip_connect_callback);
+ SOCKET_TRACE("Err %d from connect\r\n", (int)err);
+ err_code = lwip_error_convert(err);
+
+ if (err_code == NRF_SUCCESS && is_blocking)
+ {
+ err_code = lwip_wait_for_state(p_handle, TCP_STATE_CONNECTED);
+ }
+ }
+ if (err_code != NRF_SUCCESS)
+ {
+ SOCKET_TRACE("Error %d when connecting to socket\r\n", (int)err_code);
+ portdb_free(port);
+ }
+ else
+ {
+ SOCKET_TRACE("Successfully connected to remote host!\r\n");
+ }
+
+ return err_code;
+}
+
+static err_t lwip_send_complete(void * p_arg, struct tcp_pcb * p_pcb, u16_t len)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_arg;
+ if (p_handle->tcp_state == TCP_STATE_TCP_SEND_PENDING)
+ {
+ p_handle->tcp_state = TCP_STATE_DATA_TX_IN_PROGRESS;
+ }
+ return ERR_OK;
+}
+
+static inline uint32_t lwip_check_connected(socket_t * p_socket)
+{
+ return (p_socket->so_state == STATE_CONNECTED || p_socket->so_params.so_type == SOCK_DGRAM) ?
+ NRF_SUCCESS : SOCKET_NOT_CONNECTED;
+}
+
+
+static uint32_t lwip_transport_send(socket_t * p_socket,
+ const void * p_buf,
+ uint32_t buf_len,
+ int flags,
+ const void * p_destaddr,
+ socklen_t destaddr_len)
+{
+ (void) p_destaddr;
+ (void) destaddr_len;
+
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_socket->so_ctx;
+ if ((p_socket->so_flags & O_NONBLOCK) != 0 &&
+ (flags & MSG_WAITALL) == 0)
+ {
+ flags |= MSG_DONTWAIT;
+ }
+
+ uint32_t err_code = lwip_check_connected(p_socket);
+ if (err_code == NRF_SUCCESS)
+ {
+ uint32_t len = tcp_sndbuf(p_handle->p_pcb);
+ if (len >= buf_len)
+ {
+ tcp_sent(p_handle->p_pcb, lwip_send_complete);
+ p_handle->tcp_state = TCP_STATE_TCP_SEND_PENDING;
+ err_t err = tcp_write(p_handle->p_pcb, p_buf, buf_len, 1);
+ err_code = lwip_error_convert(err);
+ if (err_code == NRF_SUCCESS &&
+ (flags & MSG_DONTWAIT) == 0)
+ {
+ err_code = lwip_wait_for_state(p_handle, TCP_STATE_DATA_TX_IN_PROGRESS);
+ }
+ }
+ else
+ {
+ err_code = SOCKET_NO_MEM;
+ }
+ }
+ return err_code;
+}
+
+
+static uint32_t lwip_transport_recv(socket_t * p_socket,
+ void * p_buf,
+ uint32_t * p_buf_size,
+ int flags,
+ void * p_srcaddr,
+ socklen_t * p_srcaddr_len)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_socket->so_ctx;
+ if ((p_socket->so_flags & O_NONBLOCK) != 0 &&
+ (flags & MSG_WAITALL) == 0)
+ {
+ flags |= MSG_DONTWAIT;
+ }
+ uint32_t err_code = lwip_check_connected(p_socket);
+ if (err_code == NRF_SUCCESS)
+ {
+ if (mbuf_empty(&p_handle->mbuf) == true)
+ {
+ if ((flags & MSG_DONTWAIT) != 0)
+ {
+ err_code = SOCKET_WOULD_BLOCK;
+ }
+ else
+ {
+ while ((mbuf_empty(&p_handle->mbuf) == true) && (err_code == NRF_SUCCESS))
+ {
+ err_code = socket_wait();
+ }
+ }
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ *p_buf_size = mbuf_read(&p_handle->mbuf, p_buf, *p_buf_size);
+ tcp_recved(p_handle->p_pcb, *p_buf_size);
+ p_socket->so_read_evt = 0;
+ }
+ return err_code;
+}
+
+static err_t lwip_accept_callback(void * p_arg, struct tcp_pcb * p_pcb, err_t err)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_arg;
+ socket_t * p_socket = p_handle->p_socket;
+ if (err == ERR_OK)
+ {
+ (void) nrf_fifo_enq(&p_handle->conn_queue, p_pcb, true);
+ // TODO: Error check
+ p_socket->so_read_evt++;
+ }
+ return err;
+}
+
+static uint32_t lwip_transport_listen(socket_t * p_socket, int backlog)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_socket->so_ctx;
+ uint32_t err_code = NRF_SUCCESS;
+ struct tcp_pcb * p_pcb = tcp_listen_with_backlog(p_handle->p_pcb, backlog);
+ if (p_pcb == NULL)
+ {
+ err_code = SOCKET_ADDRESS_IN_USE;
+ }
+ else
+ {
+ p_handle->p_pcb = p_pcb;
+ tcp_accept(p_handle->p_pcb, lwip_accept_callback);
+ }
+ return err_code;
+}
+
+static uint32_t lwip_transport_accept(socket_t * p_socket,
+ socket_t * p_client,
+ void * p_cliaddr,
+ socklen_t * p_cliaddr_len)
+{
+ VERIFY_ADDRESS_LEN(*p_cliaddr_len);
+ struct tcp_pcb * p_client_pcb = NULL;
+ lwip_handle_t * p_lwip_handle = (lwip_handle_t *)p_socket->so_ctx;
+ uint32_t err_code = nrf_fifo_deq(&p_lwip_handle->conn_queue,
+ (void **)&p_client_pcb,
+ (p_socket->so_flags & O_NONBLOCK) == 0);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ lwip_handle_t * p_lwip_client = lwip_handle_allocate(p_client, p_client_pcb);
+ sockaddr_in6_t * p_sockaddr = (sockaddr_in6_t *)p_cliaddr;
+
+ p_client->so_ctx = p_lwip_client;
+
+ lwipaddr_to_sockaddr(&p_client_pcb->remote_ip, p_sockaddr);
+ p_sockaddr->sin6_port = p_client_pcb->remote_port;
+ p_sockaddr->sin6_len = *p_cliaddr_len;
+ p_sockaddr->sin6_family = AF_INET6;
+ p_sockaddr->sin6_flowinfo = 0;
+ p_sockaddr->sin6_scope_id = 0;
+
+ /*lint -save -e548 */
+ tcp_accepted(p_lwip_handle->p_pcb);
+ /*lint -restore */
+ }
+
+ return err_code;
+}
+
+/**
+ * @brief Transport for LwIP socket.
+ */
+socket_transport_t transport_impl =
+{
+ .open = lwip_transport_open,
+ .bind = lwip_transport_bind,
+ .connect = lwip_transport_connect,
+ .send = lwip_transport_send,
+ .recv = lwip_transport_recv,
+ .listen = lwip_transport_listen,
+ .accept = lwip_transport_accept,
+ .close = lwip_transport_close
+};