diff --git a/MDK-Packs.IoT_Socket.pdsc b/MDK-Packs.IoT_Socket.pdsc
index 5dbea91..1d56640 100644
--- a/MDK-Packs.IoT_Socket.pdsc
+++ b/MDK-Packs.IoT_Socket.pdsc
@@ -15,6 +15,8 @@
Active Development ...
+ Aligned return codes with the documentation
+ Added the lwIP Socket layer
@@ -81,7 +83,7 @@
-
+
IoT Socket implementation with MDK Network
@@ -92,7 +94,7 @@
-
+
IoT Socket implementation with FreeRTOS+ TCP
diff --git a/layer/FreeRTOS_Plus_TCP/README.md b/layer/FreeRTOS_Plus_TCP/README.md
index 7518acd..6e18965 100644
--- a/layer/FreeRTOS_Plus_TCP/README.md
+++ b/layer/FreeRTOS_Plus_TCP/README.md
@@ -1,5 +1,5 @@
Socket: FreeRTOS+TCP (Ethernet)
-------------------------------
-[IoT Socket](https://mdk-packs.github.io/IoT_Socket/html/index.html) interface using FreeRTOS+TCP over Ethernet via
+[IoT Socket](https://mdk-packs.github.io/IoT_Socket/latest/index.html) interface using FreeRTOS+TCP over Ethernet via
[CMSIS-Driver Ethernet](https://arm-software.github.io/CMSIS_6/latest/Driver/group__eth__interface__gr.html).
diff --git a/layer/MDK_Network_ETH/README.md b/layer/MDK_Network_ETH/README.md
index c689a39..5ccc5fd 100644
--- a/layer/MDK_Network_ETH/README.md
+++ b/layer/MDK_Network_ETH/README.md
@@ -1,6 +1,6 @@
Socket: Ethernet IoT Socket (MDK-Middleware Network)
----------------------------------------------------
-[IoT Socket](https://mdk-packs.github.io/IoT_Socket/html/index.html) interface using
+[IoT Socket](https://mdk-packs.github.io/IoT_Socket/latest/index.html) interface using
[MDK-Middleware Network](https://arm-software.github.io/MDK-Middleware/latest/Network/index.html) module via
[CMSIS-Driver Ethernet](https://arm-software.github.io/CMSIS_6/latest/Driver/index.html).
diff --git a/layer/VSocket/README.md b/layer/VSocket/README.md
index d043e90..7f2f80a 100644
--- a/layer/VSocket/README.md
+++ b/layer/VSocket/README.md
@@ -1,5 +1,5 @@
Socket: VSocket
---------------
-[IoT Socket](https://mdk-packs.github.io/IoT_Socket/html/index.html) interface using Virtual Socket on
+[IoT Socket](https://mdk-packs.github.io/IoT_Socket/latest/index.html) interface using Virtual Socket on
[Arm Virtual Hardware](https://www.arm.com/products/development-tools/simulation/virtual-hardware).
diff --git a/layer/WiFi/README.md b/layer/WiFi/README.md
index 4d34c2c..6ad2dd0 100644
--- a/layer/WiFi/README.md
+++ b/layer/WiFi/README.md
@@ -1,7 +1,7 @@
Socket: WiFi
------------
-[IoT Socket](https://mdk-packs.github.io/IoT_Socket/html/index.html) interface using WiFi module via
+[IoT Socket](https://mdk-packs.github.io/IoT_Socket/latest/index.html) interface using WiFi module via
[CMSIS-Driver WiFi](https://arm-software.github.io/CMSIS_6/latest/Driver/index.html).
The file `socket_startup.c` configures the WiFi connection with these settings:
diff --git a/layer/lwIP/README.md b/layer/lwIP/README.md
new file mode 100644
index 0000000..ecf0da2
--- /dev/null
+++ b/layer/lwIP/README.md
@@ -0,0 +1,6 @@
+Socket: Ethernet IoT Socket (lwIP)
+----------------------------------------------------
+
+[IoT Socket](https://mdk-packs.github.io/IoT_Socket/latest/index.html) interface using
+[lwIP](https://github.com/Open-CMSIS-Pack/lwIP) module via
+[CMSIS-Driver Ethernet](https://arm-software.github.io/CMSIS_6/latest/Driver/index.html).
diff --git a/layer/lwIP/RTE/Network/ethif_config.h b/layer/lwIP/RTE/Network/ethif_config.h
new file mode 100644
index 0000000..67f1b22
--- /dev/null
+++ b/layer/lwIP/RTE/Network/ethif_config.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ETHIF_CONFIG_H
+#define ETHIF_CONFIG_H
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+
+// Connect to hardware via Driver_ETH# <0-255>
+// Select driver control block for MAC and PHY interface
+#define ETH_DRV_NUM 0
+
+// Ethernet MAC Address
+// MAC Address byte 1 <0x00-0xff>
+#define MAC_ADDR0 0x02
+
+// MAC Address byte 2 <0x00-0xff>
+#define MAC_ADDR1 0x00
+
+// MAC Address byte 3 <0x00-0xff>
+#define MAC_ADDR2 0x00
+
+// MAC Address byte 4 <0x00-0xff>
+#define MAC_ADDR3 0x00
+
+// MAC Address byte 4 <0x00-0xff>
+#define MAC_ADDR4 0x00
+
+// MAC Address byte 4 <0x00-0xff>
+#define MAC_ADDR5 0x00
+//
+
+//------------- <<< end of configuration section >>> ---------------------------
+
+#endif
diff --git a/layer/lwIP/RTE/Network/ethif_config.h.base@1.0.0 b/layer/lwIP/RTE/Network/ethif_config.h.base@1.0.0
new file mode 100644
index 0000000..67f1b22
--- /dev/null
+++ b/layer/lwIP/RTE/Network/ethif_config.h.base@1.0.0
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ETHIF_CONFIG_H
+#define ETHIF_CONFIG_H
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+
+// Connect to hardware via Driver_ETH# <0-255>
+// Select driver control block for MAC and PHY interface
+#define ETH_DRV_NUM 0
+
+// Ethernet MAC Address
+// MAC Address byte 1 <0x00-0xff>
+#define MAC_ADDR0 0x02
+
+// MAC Address byte 2 <0x00-0xff>
+#define MAC_ADDR1 0x00
+
+// MAC Address byte 3 <0x00-0xff>
+#define MAC_ADDR2 0x00
+
+// MAC Address byte 4 <0x00-0xff>
+#define MAC_ADDR3 0x00
+
+// MAC Address byte 4 <0x00-0xff>
+#define MAC_ADDR4 0x00
+
+// MAC Address byte 4 <0x00-0xff>
+#define MAC_ADDR5 0x00
+//
+
+//------------- <<< end of configuration section >>> ---------------------------
+
+#endif
diff --git a/layer/lwIP/RTE/Network/lwipopts.h b/layer/lwIP/RTE/Network/lwipopts.h
new file mode 100644
index 0000000..85eda9d
--- /dev/null
+++ b/layer/lwIP/RTE/Network/lwipopts.h
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2019 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LWIP_LWIPOPTS_H
+#define LWIP_LWIPOPTS_H
+
+/* Options managed by RTE */
+#include "lwipopts_rte.h"
+
+/* See "lwip/opt.h" for all available configuration options */
+
+/*
+ ------------------------------------
+ -------------- NO SYS --------------
+ ------------------------------------
+#define NO_SYS managed by RTE
+#define LWIP_TIMERS managed by RTE
+#define SYS_LIGHTWEIGHT_PROT managed by RTE
+*/
+
+/*
+ ------------------------------------
+ ---------- Memory options ----------
+ ------------------------------------
+*/
+#define MEM_LIBC_MALLOC 0
+#define MEMP_MEM_MALLOC 1
+#define MEMP_MEM_INIT 0
+#define MEM_ALIGNMENT 4
+#define MEM_SIZE 16000
+#define MEMP_OVERFLOW_CHECK 0
+#define MEMP_SANITY_CHECK 0
+#define MEM_OVERFLOW_CHECK 0
+#define MEM_SANITY_CHECK 0
+
+/* ------------------------------------------------
+ ---------- Internal Memory Pool Sizes ----------
+ ------------------------------------------------
+ */
+#define MEMP_NUM_PBUF 10
+#define MEMP_NUM_RAW_PCB 4
+#define MEMP_NUM_UDP_PCB 6
+#define MEMP_NUM_TCP_PCB 10
+#define MEMP_NUM_TCP_PCB_LISTEN 6
+#define MEMP_NUM_TCP_SEG 12
+#define MEMP_NUM_REASSDATA 16
+#define MEMP_NUM_FRAG_PBUF 15
+#define MEMP_NUM_ARP_QUEUE 10
+#define MEMP_NUM_IGMP_GROUP 8
+#define MEMP_NUM_NETBUF 2
+#define MEMP_NUM_NETCONN 4
+#define MEMP_NUM_SELECT_CB 4
+#define MEMP_NUM_TCPIP_MSG_API 8
+#define MEMP_NUM_TCPIP_MSG_INPKT 8
+#define MEMP_NUM_NETDB 1
+#define MEMP_NUM_LOCALHOSTLIST 1
+#define PBUF_POOL_SIZE 16
+
+/*
+ ---------------------------------
+ ---------- ARP options ----------
+ ---------------------------------
+#define LWIP_ETHERNET managed by RTE
+*/
+#define LWIP_ARP 1
+#define ARP_TABLE_SIZE 10
+#define ETHARP_SUPPORT_VLAN 0
+#define ETH_PAD_SIZE 2
+#define ETHARP_SUPPORT_STATIC_ENTRIES 0
+
+/*
+ --------------------------------
+ ---------- IP options ----------
+ --------------------------------
+#define LWIP_IPV4 managed by RTE
+*/
+#define IP_FORWARD 0
+#define IP_REASSEMBLY 1
+#define IP_FRAG 1
+#define IP_OPTIONS_ALLOWED 1
+#define IP_REASS_MAX_PBUFS 10
+#define IP_DEFAULT_TTL 128
+#define IP_SOF_BROADCAST 1
+#define IP_SOF_BROADCAST_RECV 1
+
+/*
+ ----------------------------------
+ ---------- ICMP options ----------
+ ----------------------------------
+*/
+#define LWIP_ICMP 1
+
+/*
+ ---------------------------------
+ ---------- RAW options ----------
+ ---------------------------------
+*/
+#define LWIP_RAW 1
+
+/*
+ ----------------------------------
+ ---------- DHCP options ----------
+ ----------------------------------
+*/
+#define LWIP_DHCP 1
+#define LWIP_DHCP_CHECK_LINK_UP 0
+#define LWIP_DHCP_BOOTP_FILE 0
+#define LWIP_DHCP_GET_NTP_SRV 0
+#define LWIP_DHCP_MAX_NTP_SERVERS 1
+
+/*
+ ------------------------------------
+ ---------- AUTOIP options ----------
+ ------------------------------------
+*/
+#define LWIP_AUTOIP 0
+#define LWIP_DHCP_AUTOIP_COOP 0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES 9
+
+/*
+ ----------------------------------
+ ---------- IGMP options ----------
+ ----------------------------------
+*/
+#define LWIP_IGMP 0
+
+/*
+ ----------------------------------
+ ---------- DNS options -----------
+ ----------------------------------
+*/
+#define LWIP_DNS 1
+#define DNS_TABLE_SIZE 4
+#define DNS_MAX_NAME_LENGTH 256
+
+/*
+ ---------------------------------
+ ---------- UDP options ----------
+ ---------------------------------
+*/
+#define LWIP_UDP 1
+#define LWIP_UDPLITE 0
+
+/*
+ ---------------------------------
+ ---------- TCP options ----------
+ ---------------------------------
+*/
+#define LWIP_TCP 1
+#define TCP_QUEUE_OOSEQ 0
+#define LWIP_TCP_SACK_OUT 0
+#define LWIP_TCP_MAX_SACK_NUM 4
+#define TCP_MSS 1460
+#define TCP_OOSEQ_MAX_BYTES 0
+#define TCP_OOSEQ_MAX_PBUFS 0
+#define TCP_LISTEN_BACKLOG 1
+#define TCP_DEFAULT_LISTEN_BACKLOG 0xff
+#define LWIP_EVENT_API 0
+#define LWIP_CALLBACK_API 1
+#define LWIP_WND_SCALE 0
+#define TCP_RCV_SCALE 0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS 0
+#define LWIP_ALTCP 0
+#define LWIP_ALTCP_TLS 0
+
+/*
+ ----------------------------------
+ ---------- Pbuf options ----------
+ ----------------------------------
+*/
+#define PBUF_LINK_ENCAPSULATION_HLEN 0
+
+/*
+ ------------------------------------------------
+ ---------- Network Interfaces options ----------
+ ------------------------------------------------
+*/
+#define LWIP_SINGLE_NETIF 0
+#define LWIP_NETIF_HOSTNAME 0
+#define LWIP_NETIF_API 0
+#define LWIP_NETIF_STATUS_CALLBACK 1
+#define LWIP_NETIF_EXT_STATUS_CALLBACK 0
+#define LWIP_NETIF_LINK_CALLBACK 1
+#define LWIP_NETIF_REMOVE_CALLBACK 0
+#define LWIP_NETIF_HWADDRHINT 1
+
+/*
+ ------------------------------------
+ ---------- LOOPIF options ----------
+ ------------------------------------
+*/
+#define LWIP_HAVE_LOOPIF 0
+#define LWIP_LOOPIF_MULTICAST 0
+#define LWIP_NETIF_LOOPBACK 0
+#define LWIP_LOOPBACK_MAX_PBUFS 0
+
+/*
+ ------------------------------------
+ ---------- Thread options ----------
+ ------------------------------------
+*/
+#define TCPIP_THREAD_NAME "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE 0
+#define TCPIP_THREAD_PRIO osPriorityNormal
+#define TCPIP_MBOX_SIZE 16
+#define SLIPIF_THREAD_NAME "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE 0
+#define SLIPIF_THREAD_PRIO 1
+#define DEFAULT_THREAD_NAME "lwIP"
+#define DEFAULT_THREAD_STACKSIZE 0
+#define DEFAULT_THREAD_PRIO 1
+#define DEFAULT_RAW_RECVMBOX_SIZE 0
+#define DEFAULT_UDP_RECVMBOX_SIZE 4
+#define DEFAULT_TCP_RECVMBOX_SIZE 16
+#define DEFAULT_ACCEPTMBOX_SIZE 0
+
+/*
+ ----------------------------------------------
+ ---------- Sequential layer options ----------
+ ----------------------------------------------
+*/
+#define LWIP_NETCONN 0
+#define LWIP_TCPIP_TIMEOUT 1
+#define LWIP_NETCONN_SEM_PER_THREAD 0
+#define LWIP_NETCONN_FULLDUPLEX 0
+
+/*
+ ------------------------------------
+ ---------- Socket options ----------
+ ------------------------------------
+*/
+#define LWIP_SOCKET 1
+#define LWIP_COMPAT_SOCKETS 1
+#define LWIP_POSIX_SOCKETS_IO_NAMES 1
+#define LWIP_TCP_KEEPALIVE 1
+#define LWIP_SO_SNDTIMEO 1
+#define LWIP_SO_RCVTIMEO 1
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 1
+#define LWIP_SO_RCVBUF 0
+#define LWIP_SO_LINGER 0
+#define SO_REUSE 1
+#define SO_REUSE_RXTOALL 0
+#define LWIP_SOCKET_SELECT 1
+#define LWIP_SOCKET_POLL 1
+
+/*
+ ----------------------------------------
+ ---------- Statistics options ----------
+ ----------------------------------------
+*/
+#define LWIP_STATS 0
+
+/*
+ ---------------------------------------
+ ---------- IPv6 options ---------------
+ ---------------------------------------
+#define LWIP_IPV6 managed by RTE
+*/
+#define LWIP_IPV6_FORWARD 0
+#define LWIP_IPV6_FRAG 1
+#define LWIP_IPV6_REASS 1
+#define LWIP_IPV6_AUTOCONFIG 1
+#define LWIP_ICMP6 1
+#define LWIP_IPV6_MLD 0
+#define MEMP_NUM_MLD6_GROUP 4
+#define LWIP_ND6_NUM_NEIGHBORS 10
+#define LWIP_ND6_NUM_DESTINATIONS 10
+#define LWIP_ND6_NUM_PREFIXES 5
+#define LWIP_ND6_NUM_ROUTERS 3
+#define LWIP_ND6_ALLOW_RA_UPDATES 1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_IPV6_DHCP6 0
+#define LWIP_IPV6_DHCP6_STATEFUL 0
+#define LWIP_IPV6_DHCP6_STATELESS 1
+#define LWIP_DHCP6_GET_NTP_SRV 0
+#define LWIP_DHCP6_MAX_NTP_SERVERS 1
+
+#define TCP_KEEPIDLE_DEFAULT 10000
+#define TCP_KEEPINTVL_DEFAULT 2000
+
+#endif /* LWIP_LWIPOPTS_H */
diff --git a/layer/lwIP/RTE/Network/lwipopts.h.base@2.2.0 b/layer/lwIP/RTE/Network/lwipopts.h.base@2.2.0
new file mode 100644
index 0000000..afc0383
--- /dev/null
+++ b/layer/lwIP/RTE/Network/lwipopts.h.base@2.2.0
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2019 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LWIP_LWIPOPTS_H
+#define LWIP_LWIPOPTS_H
+
+/* Options managed by RTE */
+#include "lwipopts_rte.h"
+
+/* See "lwip/opt.h" for all available configuration options */
+
+/*
+ ------------------------------------
+ -------------- NO SYS --------------
+ ------------------------------------
+#define NO_SYS managed by RTE
+#define LWIP_TIMERS managed by RTE
+#define SYS_LIGHTWEIGHT_PROT managed by RTE
+*/
+
+/*
+ ------------------------------------
+ ---------- Memory options ----------
+ ------------------------------------
+*/
+#define MEM_LIBC_MALLOC 0
+#define MEMP_MEM_MALLOC 1
+#define MEMP_MEM_INIT 0
+#define MEM_ALIGNMENT 4
+#define MEM_SIZE (10*1024)
+#define MEMP_OVERFLOW_CHECK 0
+#define MEMP_SANITY_CHECK 0
+#define MEM_OVERFLOW_CHECK 0
+#define MEM_SANITY_CHECK 0
+
+/* ------------------------------------------------
+ ---------- Internal Memory Pool Sizes ----------
+ ------------------------------------------------
+ */
+#define MEMP_NUM_PBUF 10
+#define MEMP_NUM_RAW_PCB 4
+#define MEMP_NUM_UDP_PCB 6
+#define MEMP_NUM_TCP_PCB 10
+#define MEMP_NUM_TCP_PCB_LISTEN 6
+#define MEMP_NUM_TCP_SEG 12
+#define MEMP_NUM_REASSDATA 16
+#define MEMP_NUM_FRAG_PBUF 15
+#define MEMP_NUM_ARP_QUEUE 10
+#define MEMP_NUM_IGMP_GROUP 8
+#define MEMP_NUM_NETBUF 2
+#define MEMP_NUM_NETCONN 4
+#define MEMP_NUM_SELECT_CB 4
+#define MEMP_NUM_TCPIP_MSG_API 8
+#define MEMP_NUM_TCPIP_MSG_INPKT 8
+#define MEMP_NUM_NETDB 1
+#define MEMP_NUM_LOCALHOSTLIST 1
+#define PBUF_POOL_SIZE 16
+
+/*
+ ---------------------------------
+ ---------- ARP options ----------
+ ---------------------------------
+#define LWIP_ETHERNET managed by RTE
+*/
+#define LWIP_ARP 1
+#define ARP_TABLE_SIZE 10
+#define ETHARP_SUPPORT_VLAN 0
+#define ETH_PAD_SIZE 2
+#define ETHARP_SUPPORT_STATIC_ENTRIES 0
+
+/*
+ --------------------------------
+ ---------- IP options ----------
+ --------------------------------
+#define LWIP_IPV4 managed by RTE
+*/
+#define IP_FORWARD 0
+#define IP_REASSEMBLY 1
+#define IP_FRAG 1
+#define IP_OPTIONS_ALLOWED 1
+#define IP_REASS_MAX_PBUFS 10
+#define IP_DEFAULT_TTL 128
+#define IP_SOF_BROADCAST 1
+#define IP_SOF_BROADCAST_RECV 1
+
+/*
+ ----------------------------------
+ ---------- ICMP options ----------
+ ----------------------------------
+*/
+#define LWIP_ICMP 1
+
+/*
+ ---------------------------------
+ ---------- RAW options ----------
+ ---------------------------------
+*/
+#define LWIP_RAW 1
+
+/*
+ ----------------------------------
+ ---------- DHCP options ----------
+ ----------------------------------
+*/
+#define LWIP_DHCP 1
+#define LWIP_DHCP_CHECK_LINK_UP 0
+#define LWIP_DHCP_BOOTP_FILE 0
+#define LWIP_DHCP_GET_NTP_SRV 0
+#define LWIP_DHCP_MAX_NTP_SERVERS 1
+
+/*
+ ------------------------------------
+ ---------- AUTOIP options ----------
+ ------------------------------------
+*/
+#define LWIP_AUTOIP 0
+#define LWIP_DHCP_AUTOIP_COOP 0
+#define LWIP_DHCP_AUTOIP_COOP_TRIES 9
+
+/*
+ ----------------------------------
+ ---------- IGMP options ----------
+ ----------------------------------
+*/
+#define LWIP_IGMP 0
+
+/*
+ ----------------------------------
+ ---------- DNS options -----------
+ ----------------------------------
+*/
+#define LWIP_DNS 0
+#define DNS_TABLE_SIZE 4
+#define DNS_MAX_NAME_LENGTH 256
+
+/*
+ ---------------------------------
+ ---------- UDP options ----------
+ ---------------------------------
+*/
+#define LWIP_UDP 1
+#define LWIP_UDPLITE 0
+
+/*
+ ---------------------------------
+ ---------- TCP options ----------
+ ---------------------------------
+*/
+#define LWIP_TCP 1
+#define TCP_QUEUE_OOSEQ 0
+#define LWIP_TCP_SACK_OUT 0
+#define LWIP_TCP_MAX_SACK_NUM 4
+#define TCP_MSS 1460
+#define TCP_OOSEQ_MAX_BYTES 0
+#define TCP_OOSEQ_MAX_PBUFS 0
+#define TCP_LISTEN_BACKLOG 1
+#define TCP_DEFAULT_LISTEN_BACKLOG 0xff
+#define LWIP_EVENT_API 0
+#define LWIP_CALLBACK_API 1
+#define LWIP_WND_SCALE 0
+#define TCP_RCV_SCALE 0
+#define LWIP_TCP_PCB_NUM_EXT_ARGS 0
+#define LWIP_ALTCP 0
+#define LWIP_ALTCP_TLS 0
+
+/*
+ ----------------------------------
+ ---------- Pbuf options ----------
+ ----------------------------------
+*/
+#define PBUF_LINK_ENCAPSULATION_HLEN 0
+
+/*
+ ------------------------------------------------
+ ---------- Network Interfaces options ----------
+ ------------------------------------------------
+*/
+#define LWIP_SINGLE_NETIF 0
+#define LWIP_NETIF_HOSTNAME 0
+#define LWIP_NETIF_API 0
+#define LWIP_NETIF_STATUS_CALLBACK 1
+#define LWIP_NETIF_EXT_STATUS_CALLBACK 0
+#define LWIP_NETIF_LINK_CALLBACK 1
+#define LWIP_NETIF_REMOVE_CALLBACK 0
+#define LWIP_NETIF_HWADDRHINT 1
+
+/*
+ ------------------------------------
+ ---------- LOOPIF options ----------
+ ------------------------------------
+*/
+#define LWIP_HAVE_LOOPIF 0
+#define LWIP_LOOPIF_MULTICAST 0
+#define LWIP_NETIF_LOOPBACK 0
+#define LWIP_LOOPBACK_MAX_PBUFS 0
+
+/*
+ ------------------------------------
+ ---------- Thread options ----------
+ ------------------------------------
+*/
+#define TCPIP_THREAD_NAME "tcpip_thread"
+#define TCPIP_THREAD_STACKSIZE 0
+#define TCPIP_THREAD_PRIO 1
+#define TCPIP_MBOX_SIZE 0
+#define SLIPIF_THREAD_NAME "slipif_loop"
+#define SLIPIF_THREAD_STACKSIZE 0
+#define SLIPIF_THREAD_PRIO 1
+#define DEFAULT_THREAD_NAME "lwIP"
+#define DEFAULT_THREAD_STACKSIZE 0
+#define DEFAULT_THREAD_PRIO 1
+#define DEFAULT_RAW_RECVMBOX_SIZE 0
+#define DEFAULT_UDP_RECVMBOX_SIZE 0
+#define DEFAULT_TCP_RECVMBOX_SIZE 0
+#define DEFAULT_ACCEPTMBOX_SIZE 0
+
+/*
+ ----------------------------------------------
+ ---------- Sequential layer options ----------
+ ----------------------------------------------
+*/
+#define LWIP_NETCONN 0
+#define LWIP_TCPIP_TIMEOUT 1
+#define LWIP_NETCONN_SEM_PER_THREAD 0
+#define LWIP_NETCONN_FULLDUPLEX 0
+
+/*
+ ------------------------------------
+ ---------- Socket options ----------
+ ------------------------------------
+*/
+#define LWIP_SOCKET 0
+#define LWIP_COMPAT_SOCKETS 1
+#define LWIP_POSIX_SOCKETS_IO_NAMES 1
+#define LWIP_TCP_KEEPALIVE 1
+#define LWIP_SO_SNDTIMEO 0
+#define LWIP_SO_RCVTIMEO 0
+#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0
+#define LWIP_SO_RCVBUF 0
+#define LWIP_SO_LINGER 0
+#define SO_REUSE 0
+#define SO_REUSE_RXTOALL 0
+#define LWIP_SOCKET_SELECT 1
+#define LWIP_SOCKET_POLL 1
+
+/*
+ ----------------------------------------
+ ---------- Statistics options ----------
+ ----------------------------------------
+*/
+#define LWIP_STATS 0
+
+/*
+ --------------------------------------
+ ---------- Checksum options ----------
+ --------------------------------------
+*/
+#define LWIP_CHECKSUM_CTRL_PER_NETIF 0
+
+/*
+ ---------------------------------------
+ ---------- IPv6 options ---------------
+ ---------------------------------------
+#define LWIP_IPV6 managed by RTE
+*/
+#define LWIP_IPV6_FORWARD 0
+#define LWIP_IPV6_FRAG 1
+#define LWIP_IPV6_REASS 1
+#define LWIP_IPV6_AUTOCONFIG 1
+#define LWIP_ICMP6 1
+#define LWIP_IPV6_MLD 0
+#define MEMP_NUM_MLD6_GROUP 4
+#define LWIP_ND6_NUM_NEIGHBORS 10
+#define LWIP_ND6_NUM_DESTINATIONS 10
+#define LWIP_ND6_NUM_PREFIXES 5
+#define LWIP_ND6_NUM_ROUTERS 3
+#define LWIP_ND6_ALLOW_RA_UPDATES 1
+#define LWIP_ND6_TCP_REACHABILITY_HINTS 1
+#define LWIP_IPV6_DHCP6 0
+#define LWIP_IPV6_DHCP6_STATEFUL 0
+#define LWIP_IPV6_DHCP6_STATELESS 1
+#define LWIP_DHCP6_GET_NTP_SRV 0
+#define LWIP_DHCP6_MAX_NTP_SERVERS 1
+
+#endif /* LWIP_LWIPOPTS_H */
diff --git a/layer/lwIP/Socket.clayer.yml b/layer/lwIP/Socket.clayer.yml
new file mode 100644
index 0000000..896df24
--- /dev/null
+++ b/layer/lwIP/Socket.clayer.yml
@@ -0,0 +1,28 @@
+layer:
+ type: Socket
+ description: IoT Socket interface using lwIP over Ethernet
+
+ connections:
+ - connect: lwIP Socket
+ consumes:
+ - CMSIS_ETH
+ - CMSIS-RTOS2
+ provides:
+ - IoT_Socket
+
+ packs:
+ - pack: MDK-Packs::IoT_Socket@^1.4.0
+ - pack: lwIP::lwIP@^2.3.0
+
+ components:
+ - component: IoT Utility:Socket:lwIP
+ - component: Network&lwIP:API
+ - component: Network&lwIP:CORE&IPv4
+ - component: Network&lwIP:RTOS&CMSIS-RTOS2
+ - component: Network&lwIP:Driver:Ethernet&CMSIS Driver
+ - component: Network&lwIP:Interface:Ethernet
+
+ groups:
+ - group: Socket
+ files:
+ - file: ./socket_startup.c
diff --git a/layer/lwIP/socket_startup.c b/layer/lwIP/socket_startup.c
new file mode 100644
index 0000000..00aa5f9
--- /dev/null
+++ b/layer/lwIP/socket_startup.c
@@ -0,0 +1,68 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2020-2026 Arm Limited (or its affiliates). All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * -------------------------------------------------------------------------- */
+
+#include "cmsis_os2.h"
+#include "ethernetif.h"
+#include "lwip/tcpip.h"
+#include "lwip/dhcp.h"
+
+#define ETH0_THREAD_STACKSIZE 1024U
+
+static struct netif netif;
+
+static void eth0_thread (void *argument) {
+ uint32_t ms,sys_old = 0U;
+
+ while (1) {
+ ethernetif_poll (&netif);
+ ms = sys_now () - sys_old;
+ if (ms >= 500U) {
+ sys_old += ms;
+ ethernetif_check_link (&netif);
+ }
+ osDelay (2U);
+ }
+}
+
+static void lwip_add_eth (void *arg) {
+ static const osThreadAttr_t eth0_attr = {
+ .name = "eth0_thread",
+ .stack_size = ETH0_THREAD_STACKSIZE
+ };
+
+ // Add network interface
+ netif_add(&netif, NULL, NULL, NULL, NULL, ðernetif_init, &tcpip_input);
+
+ // Register default interface
+ netif_set_default(&netif);
+ netif_set_up(&netif);
+ dhcp_start (&netif);
+
+ osThreadNew(eth0_thread, NULL, ð0_attr);
+}
+
+int32_t socket_startup (void) {
+
+ tcpip_init (lwip_add_eth, NULL);
+
+ do {
+ osDelay (500U);
+ } while (netif.ip_addr.addr == IPADDR_ANY);
+
+ return 0;
+}
diff --git a/source/freertos_plus_tcp/iot_socket.c b/source/freertos_plus_tcp/iot_socket.c
index 433b2b8..4e9939b 100644
--- a/source/freertos_plus_tcp/iot_socket.c
+++ b/source/freertos_plus_tcp/iot_socket.c
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------------
- * Copyright (c) 2022-2024 Arm Limited (or its affiliates). All rights reserved.
+ * Copyright (c) 2022-2026 Arm Limited (or its affiliates). All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -30,19 +30,32 @@ int32_t iotSocketCreate (int32_t af, int32_t type, int32_t protocol) {
if (af != IOT_SOCKET_AF_INET) {
/* Only IPv4 sockets are supported */
- return IOT_SOCKET_ENOTSUP;
+ return IOT_SOCKET_EINVAL;
}
- if (type == IOT_SOCKET_SOCK_STREAM) {
- xType = FREERTOS_SOCK_STREAM;
- } else {
- xType = FREERTOS_SOCK_DGRAM;
+ switch (type) {
+ case IOT_SOCKET_SOCK_STREAM:
+ xType = FREERTOS_SOCK_STREAM;
+ break;
+ case IOT_SOCKET_SOCK_DGRAM:
+ xType = FREERTOS_SOCK_DGRAM;
+ break;
+ default:
+ return IOT_SOCKET_EINVAL;
}
- if (type == IOT_SOCKET_IPPROTO_TCP) {
- xProtocol = FREERTOS_IPPROTO_TCP;
- } else {
- xProtocol = FREERTOS_IPPROTO_UDP;
+ switch (protocol) {
+ case 0:
+ /* FREERTOS_SOCK_DEPENDENT_PROTO */
+ break;
+ case IOT_SOCKET_IPPROTO_TCP:
+ xProtocol = FREERTOS_IPPROTO_TCP;
+ break;
+ case IOT_SOCKET_IPPROTO_UDP:
+ xProtocol = FREERTOS_IPPROTO_UDP;
+ break;
+ default:
+ return IOT_SOCKET_EINVAL;
}
xSocket = FreeRTOS_socket (FREERTOS_AF_INET, xType, xProtocol);
@@ -60,7 +73,7 @@ int32_t iotSocketCreate (int32_t af, int32_t type, int32_t protocol) {
// Assign a local address to a socket
int32_t iotSocketBind (int32_t socket, const uint8_t *ip, uint32_t ip_len, uint16_t port) {
- Socket_t xSocket =(Socket_t)socket;
+ Socket_t xSocket = (Socket_t)socket;
struct freertos_sockaddr pxAddress;
BaseType_t rval;
int32_t stat;
@@ -72,7 +85,7 @@ int32_t iotSocketBind (int32_t socket, const uint8_t *ip, uint32_t ip_len, uint1
pxAddress.sin_addr = FreeRTOS_inet_addr_quick (ip[0], ip[1], ip[2], ip[3]);
pxAddress.sin_port = FreeRTOS_htons (port);
- rval = FreeRTOS_bind (xSocket, &pxAddress, sizeof(struct freertos_sockaddr));
+ rval = FreeRTOS_bind (xSocket, &pxAddress, sizeof(pxAddress));
if (rval == 0) {
/* Socket bound */
@@ -92,7 +105,7 @@ int32_t iotSocketBind (int32_t socket, const uint8_t *ip, uint32_t ip_len, uint1
// Listen for socket connections
int32_t iotSocketListen (int32_t socket, int32_t backlog) {
- Socket_t xSocket =(Socket_t)socket;
+ Socket_t xSocket = (Socket_t)socket;
BaseType_t rval;
int32_t stat;
@@ -112,7 +125,7 @@ int32_t iotSocketListen (int32_t socket, int32_t backlog) {
// Accept a new connection on a socket
int32_t iotSocketAccept (int32_t socket, uint8_t *ip, uint32_t *ip_len, uint16_t *port) {
- Socket_t xSocket =(Socket_t)socket;
+ Socket_t xSocket = (Socket_t)socket;
struct freertos_sockaddr xAddress;
socklen_t xAddressLength;
Socket_t xAccept;
@@ -147,7 +160,7 @@ int32_t iotSocketAccept (int32_t socket, uint8_t *ip, uint32_t *ip_len, uint16_t
if (port != NULL) {
/* Copy remote port */
- *port = FreeRTOS_htons (xAddress.sin_port);
+ *port = FreeRTOS_ntohs (xAddress.sin_port);
}
}
@@ -156,7 +169,7 @@ int32_t iotSocketAccept (int32_t socket, uint8_t *ip, uint32_t *ip_len, uint16_t
// Connect a socket to a remote host
int32_t iotSocketConnect (int32_t socket, const uint8_t *ip, uint32_t ip_len, uint16_t port) {
- Socket_t xSocket =(Socket_t)socket;
+ Socket_t xSocket = (Socket_t)socket;
struct freertos_sockaddr xAddress;
BaseType_t rval;
int32_t stat;
@@ -168,11 +181,15 @@ int32_t iotSocketConnect (int32_t socket, const uint8_t *ip, uint32_t ip_len, ui
xAddress.sin_addr = FreeRTOS_inet_addr_quick (ip[0], ip[1], ip[2], ip[3]);
xAddress.sin_port = FreeRTOS_htons (port);
- rval = FreeRTOS_connect (xSocket, &xAddress, sizeof(struct freertos_sockaddr));
+ rval = FreeRTOS_connect (xSocket, &xAddress, sizeof(xAddress));
if (rval == 0) {
/* Connect succeeded */
- stat = 0U;
+ stat = 0;
+ }
+ else if (rval == -pdFREERTOS_ERRNO_EINVAL) {
+ /* Invalid parameter value */
+ stat = IOT_SOCKET_EINVAL;
}
else if (rval == -pdFREERTOS_ERRNO_EBADF) {
/* Not a valid TCP socket */
@@ -187,19 +204,19 @@ int32_t iotSocketConnect (int32_t socket, const uint8_t *ip, uint32_t ip_len, ui
stat = IOT_SOCKET_EALREADY;
}
else if (rval == -pdFREERTOS_ERRNO_EAGAIN) {
- /* Socket state does not allows a connect operation */
- stat = IOT_SOCKET_ECONNABORTED;
+ /* Socket state does not allow a connect operation */
+ stat = IOT_SOCKET_EINVAL;
}
else if (rval == -pdFREERTOS_ERRNO_EWOULDBLOCK) {
- /* Operation would block */
- stat = IOT_SOCKET_ECONNABORTED;
+ /* Operation would block, connect attempt started */
+ stat = IOT_SOCKET_EINPROGRESS;
}
else if (rval == -pdFREERTOS_ERRNO_ETIMEDOUT) {
/* Connect attempt timed out */
stat = IOT_SOCKET_ETIMEDOUT;
}
- else /* rval == -pdFREERTOS_ERRNO_EINVAL */ {
- stat = IOT_SOCKET_EINVAL;
+ else {
+ stat = IOT_SOCKET_ERROR;
}
return stat;
@@ -207,7 +224,7 @@ int32_t iotSocketConnect (int32_t socket, const uint8_t *ip, uint32_t ip_len, ui
// Receive data on a connected socket
int32_t iotSocketRecv (int32_t socket, void *buf, uint32_t len) {
- Socket_t xSocket =(Socket_t)socket;
+ Socket_t xSocket = (Socket_t)socket;
BaseType_t rval;
int32_t stat;
@@ -218,8 +235,12 @@ int32_t iotSocketRecv (int32_t socket, void *buf, uint32_t len) {
if (rval == -pdFREERTOS_ERRNO_EINVAL) {
/* Not a TCP socket */
stat = IOT_SOCKET_EINVAL;
- } else {
- stat = (int32_t)rval;
+ }
+ else if (rval > 0) {
+ stat = 0;
+ }
+ else {
+ stat = IOT_SOCKET_EAGAIN;
}
}
else if (buf == NULL) {
@@ -256,7 +277,7 @@ int32_t iotSocketRecv (int32_t socket, void *buf, uint32_t len) {
// Receive data on a socket
int32_t iotSocketRecvFrom (int32_t socket, void *buf, uint32_t len, uint8_t *ip, uint32_t *ip_len, uint16_t *port) {
- Socket_t xSocket =(Socket_t)socket;
+ Socket_t xSocket = (Socket_t)socket;
struct freertos_sockaddr xAddress;
socklen_t xAddressLength;
BaseType_t rval;
@@ -270,8 +291,12 @@ int32_t iotSocketRecvFrom (int32_t socket, void *buf, uint32_t len, uint8_t *ip,
if (rval == -pdFREERTOS_ERRNO_EINVAL) {
/* Not a TCP socket */
stat = IOT_SOCKET_EINVAL;
- } else {
- stat = (int32_t)rval;
+ }
+ else if (rval > 0) {
+ stat = 0;
+ }
+ else {
+ stat = IOT_SOCKET_EAGAIN;
}
}
else if (buf == NULL) {
@@ -324,7 +349,7 @@ int32_t iotSocketRecvFrom (int32_t socket, void *buf, uint32_t len, uint8_t *ip,
// Send data on a connected socket
int32_t iotSocketSend (int32_t socket, const void *buf, uint32_t len) {
- Socket_t xSocket =(Socket_t)socket;
+ Socket_t xSocket = (Socket_t)socket;
struct freertos_sockaddr xAddress;
socklen_t xAddressLength;
BaseType_t rval;
@@ -375,7 +400,7 @@ int32_t iotSocketSend (int32_t socket, const void *buf, uint32_t len) {
// Send data on a socket
int32_t iotSocketSendTo (int32_t socket, const void *buf, uint32_t len, const uint8_t *ip, uint32_t ip_len, uint16_t port) {
- Socket_t xSocket =(Socket_t)socket;
+ Socket_t xSocket = (Socket_t)socket;
struct freertos_sockaddr xAddress;
BaseType_t rval;
int32_t stat;
@@ -399,7 +424,7 @@ int32_t iotSocketSendTo (int32_t socket, const void *buf, uint32_t len, const ui
xAddress.sin_addr = FreeRTOS_inet_addr_quick (ip[0], ip[1], ip[2], ip[3]);
xAddress.sin_port = FreeRTOS_htons (port);
- rval = FreeRTOS_sendto (xSocket, buf, len, 0U, &xAddress, sizeof(struct freertos_sockaddr));
+ rval = FreeRTOS_sendto (xSocket, buf, len, 0U, &xAddress, sizeof(xAddress));
/* Number of bytes queued for sending, 0 on error or timeout */
stat = (int32_t)rval;
@@ -410,7 +435,7 @@ int32_t iotSocketSendTo (int32_t socket, const void *buf, uint32_t len, const ui
// Retrieve local IP address and port of a socket
int32_t iotSocketGetSockName (int32_t socket, uint8_t *ip, uint32_t *ip_len, uint16_t *port) {
- Socket_t xSocket =(Socket_t)socket;
+ Socket_t xSocket = (Socket_t)socket;
struct freertos_sockaddr xAddress;
size_t rval;
int32_t stat;
@@ -436,7 +461,7 @@ int32_t iotSocketGetSockName (int32_t socket, uint8_t *ip, uint32_t *ip_len, uin
// Retrieve remote IP address and port of a socket
int32_t iotSocketGetPeerName (int32_t socket, uint8_t *ip, uint32_t *ip_len, uint16_t *port) {
- Socket_t xSocket =(Socket_t)socket;
+ Socket_t xSocket = (Socket_t)socket;
struct freertos_sockaddr xAddress;
size_t rval;
int32_t stat;
@@ -469,7 +494,7 @@ int32_t iotSocketGetPeerName (int32_t socket, uint8_t *ip, uint32_t *ip_len, uin
// Get socket option
int32_t iotSocketGetOpt (int32_t socket, int32_t opt_id, void *opt_val, uint32_t *opt_len) {
- Socket_t xSocket =(Socket_t)socket;
+ Socket_t xSocket = (Socket_t)socket;
BaseType_t rval;
int32_t stat;
@@ -506,7 +531,7 @@ int32_t iotSocketGetOpt (int32_t socket, int32_t opt_id, void *opt_val, uint32_t
// Set socket option
int32_t iotSocketSetOpt (int32_t socket, int32_t opt_id, const void *opt_val, uint32_t opt_len) {
- Socket_t xSocket =(Socket_t)socket;
+ Socket_t xSocket = (Socket_t)socket;
BaseType_t rval;
TickType_t xTimeout;
int32_t stat;
@@ -581,7 +606,7 @@ int32_t iotSocketSetOpt (int32_t socket, int32_t opt_id, const void *opt_val, ui
stat = IOT_SOCKET_ENOTSUP;
}
else {
- stat = IOT_SOCKET_EINVAL;
+ stat = IOT_SOCKET_EINVAL;
}
return stat;
@@ -589,7 +614,7 @@ int32_t iotSocketSetOpt (int32_t socket, int32_t opt_id, const void *opt_val, ui
// Close and release a socket
int32_t iotSocketClose (int32_t socket) {
- Socket_t xSocket =(Socket_t)socket;
+ Socket_t xSocket = (Socket_t)socket;
BaseType_t rval;
TickType_t xTimeout;
int32_t stat;
diff --git a/source/mdk_network/iot_socket.c b/source/mdk_network/iot_socket.c
index 6c039cd..3d7b384 100644
--- a/source/mdk_network/iot_socket.c
+++ b/source/mdk_network/iot_socket.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2024 Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2026 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -18,6 +18,7 @@
#include
#include "iot_socket.h"
+#include "cmsis_os2.h"
#include "rl_net.h"
#include "RTE_Components.h"
@@ -194,7 +195,11 @@ int32_t iotSocketBind (int32_t socket, const uint8_t *ip, uint32_t ip_len, uint1
}
rc = bind(socket, (SOCKADDR *)&addr, addr_len);
- rc = rc_bsd_to_iot(rc);
+ if (rc == BSD_EISCONN) {
+ rc = IOT_SOCKET_ERROR;
+ } else {
+ rc = rc_bsd_to_iot(rc);
+ }
return rc;
}
@@ -411,15 +416,23 @@ static int32_t socket_check_write (int32_t socket) {
// Send data on a connected socket
int32_t iotSocketSend (int32_t socket, const void *buf, uint32_t len) {
+ int32_t retry;
int32_t rc;
if (len == 0U) {
return socket_check_write (socket);
}
- rc = send(socket, buf, (int32_t)len, 0);
+ for (retry = 0U; retry < 5U; retry++) {
+ rc = send(socket, buf, (int32_t)len, 0);
+ if (rc != BSD_ENOMEM) {
+ break;
+ }
+ osDelay (retry + 2U);
+ }
+
if (rc < 0) {
- if (rc == BSD_ETIMEDOUT) {
+ if ((rc == BSD_ETIMEDOUT) || (rc == BSD_ENOMEM)) {
rc = IOT_SOCKET_EAGAIN;
} else {
rc = rc_bsd_to_iot(rc);
@@ -469,6 +482,9 @@ int32_t iotSocketSendTo (int32_t socket, const void *buf, uint32_t len, const ui
if (rc < 0) {
if (rc == BSD_ETIMEDOUT) {
rc = IOT_SOCKET_EAGAIN;
+ } else if (rc == BSD_ENOMEM) {
+ osDelay (5U);
+ rc = IOT_SOCKET_EAGAIN;
} else {
rc = rc_bsd_to_iot(rc);
}