Skip to content

Commit 02eaad4

Browse files
authored
Merge pull request #10476 from tymoteuszblochmobica/closetcp
LWIP TCP socket close - disconnecting fix
2 parents 5be51a5 + 51610cc commit 02eaad4

File tree

4 files changed

+26
-2
lines changed

4 files changed

+26
-2
lines changed

features/lwipstack/LWIPStack.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,12 @@ void LWIP::socket_callback(struct netconn *nc, enum netconn_evt eh, u16_t len)
5050
}
5151

5252
LWIP &lwip = LWIP::get_instance();
53-
5453
lwip.adaptation.lock();
5554

55+
if (eh == NETCONN_EVT_RCVPLUS && nc->state == NETCONN_NONE) {
56+
lwip._event_flag.set(TCP_CLOSED_FLAG);
57+
}
58+
5659
for (int i = 0; i < MEMP_NUM_NETCONN; i++) {
5760
if (lwip.arena[i].in_use
5861
&& lwip.arena[i].conn == nc
@@ -292,7 +295,17 @@ nsapi_error_t LWIP::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
292295
nsapi_error_t LWIP::socket_close(nsapi_socket_t handle)
293296
{
294297
struct mbed_lwip_socket *s = (struct mbed_lwip_socket *)handle;
295-
298+
#if LWIP_TCP
299+
/* Check if TCP FSM is in ESTABLISHED state.
300+
* Then give extra time for connection close handshaking until TIME_WAIT state.
301+
* The purpose is to prevent eth/wifi driver stop and FIN ACK corrupt.
302+
* This may happend if network interface disconnect follows immediately after socket_close.*/
303+
if (NETCONNTYPE_GROUP(s->conn->type) == NETCONN_TCP && s->conn->pcb.tcp->state == ESTABLISHED) {
304+
_event_flag.clear(TCP_CLOSED_FLAG);
305+
netconn_shutdown(s->conn, false, true);
306+
_event_flag.wait_any(TCP_CLOSED_FLAG, TCP_CLOSE_TIMEOUT);
307+
}
308+
#endif
296309
netbuf_delete(s->buf);
297310
err_t err = netconn_delete(s->conn);
298311
arena_dealloc(s);

features/lwipstack/LWIPStack.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,8 @@ class LWIP : public OnboardNetworkStack, private mbed::NonCopyable<LWIP> {
587587
LWIPMemoryManager memory_manager;
588588
osThreadId tcpip_thread_id;
589589
rtos::Mutex adaptation;
590+
rtos::EventFlags _event_flag;
591+
static const int TCP_CLOSED_FLAG = 0x4u;
590592
};
591593

592594
#endif /* LWIPSTACK_H_ */

features/lwipstack/lwipopts.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,11 @@
246246
#define LWIP_TCP 1
247247
#define TCP_OVERSIZE 0
248248
#define LWIP_TCP_KEEPALIVE 1
249+
#ifdef MBED_CONF_TCP_CLOSE_TIMEOUT
250+
#define TCP_CLOSE_TIMEOUT MBED_CONF_TCP_CLOSE_TIMEOUT
251+
#else
252+
#define TCP_CLOSE_TIMEOUT 1000
253+
#endif
249254
#else
250255
#define LWIP_TCP 0
251256
#endif

features/lwipstack/mbed_lib.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@
100100
"help": "Maximum number of retransmissions of SYN segments. Current default (used if null here) is set to 6 in opt.h",
101101
"value": null
102102
},
103+
"tcp-close-timeout": {
104+
"help": "Maximum timeout (ms) for TCP close handshaking timeout",
105+
"value": 1000
106+
},
103107
"pbuf-pool-size": {
104108
"help": "Number of pbufs in pool - usually used for received packets, so this determines how much data can be buffered between reception and the application reading. If a driver uses PBUF_RAM for reception, less pool may be needed. Current default (used if null here) is set to 5 in lwipopts.h, unless overridden by target Ethernet drivers.",
105109
"value": null

0 commit comments

Comments
 (0)