Commit 6f140202 authored by Deomid Ryabkov's avatar Deomid Ryabkov Committed by Cesanta Bot

Fix LWIP net_if when RTOS is used; use for ESP32

All calls to core LWIP APIs should go through the tcpip thread.

PUBLISHED_FROM=ebe8c7f043394a75a46810f2b6626582c63b9e68
parent cfe77a3d
...@@ -14051,15 +14051,31 @@ void mg_lwip_mgr_schedule_poll(struct mg_mgr *mgr); ...@@ -14051,15 +14051,31 @@ void mg_lwip_mgr_schedule_poll(struct mg_mgr *mgr);
/* Amalgamated: #include "common/mg_mem.h" */ /* Amalgamated: #include "common/mg_mem.h" */
#include <lwip/init.h>
#include <lwip/pbuf.h> #include <lwip/pbuf.h>
#include <lwip/tcp.h> #include <lwip/tcp.h>
#if CS_PLATFORM != CS_P_STM32 #include <lwip/tcpip.h>
#if LWIP_VERSION >= 0x01050000
#include <lwip/priv/tcpip_priv.h> /* For tcp_seg */
#else
#include <lwip/tcp_impl.h> #include <lwip/tcp_impl.h>
#endif #endif
#include <lwip/udp.h> #include <lwip/udp.h>
/* Amalgamated: #include "common/cs_dbg.h" */ /* Amalgamated: #include "common/cs_dbg.h" */
/*
* Newest versions of LWIP have ip_2_ip4, older have ipX_2_ip,
* even older have nothing.
*/
#ifndef ip_2_ip4
#ifdef ipX_2_ip
#define ip_2_ip4(addr) ipX_2_ip(addr)
#else
#define ip_2_ip4(addr) (addr)
#endif
#endif
/* /*
* Depending on whether Mongoose is compiled with ipv6 support, use right * Depending on whether Mongoose is compiled with ipv6 support, use right
* lwip functions * lwip functions
...@@ -14077,16 +14093,12 @@ void mg_lwip_mgr_schedule_poll(struct mg_mgr *mgr); ...@@ -14077,16 +14093,12 @@ void mg_lwip_mgr_schedule_poll(struct mg_mgr *mgr);
#define TCP_BIND tcp_bind #define TCP_BIND tcp_bind
#define UDP_BIND udp_bind #define UDP_BIND udp_bind
#define IPADDR_NTOA ipaddr_ntoa #define IPADDR_NTOA ipaddr_ntoa
#define SET_ADDR(dst, src) (dst)->sin.sin_addr.s_addr = GET_IPV4(src) #define SET_ADDR(dst, src) (dst)->sin.sin_addr.s_addr = ip_2_ip4(src)->addr
#endif #endif
/* #if NO_SYS
* If lwip is compiled with ipv6 support, then API changes even for ipv4 #define tcpip_callback(fn, arg) (fn)(arg)
*/ typedef void (*tcpip_callback_fn)(void *arg);
#if !defined(LWIP_IPV6) || !LWIP_IPV6
#define GET_IPV4(ipX_addr) ((ipX_addr)->addr)
#else
#define GET_IPV4(ipX_addr) ((ipX_addr)->ip4.addr)
#endif #endif
void mg_lwip_ssl_do_hs(struct mg_connection *nc); void mg_lwip_ssl_do_hs(struct mg_connection *nc);
...@@ -14256,8 +14268,17 @@ static err_t mg_lwip_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb, ...@@ -14256,8 +14268,17 @@ static err_t mg_lwip_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb,
return ERR_OK; return ERR_OK;
} }
void mg_lwip_if_connect_tcp(struct mg_connection *nc, struct mg_lwip_if_connect_tcp_ctx {
const union socket_address *sa) { struct mg_connection *nc;
const union socket_address *sa;
};
static void mg_lwip_if_connect_tcp_tcpip(void *arg) {
struct mg_lwip_if_connect_tcp_ctx *ctx =
(struct mg_lwip_if_connect_tcp_ctx *) arg;
struct mg_connection *nc = ctx->nc;
const union socket_address *sa = ctx->sa;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
struct tcp_pcb *tpcb = TCP_NEW(); struct tcp_pcb *tpcb = TCP_NEW();
cs->pcb.tcp = tpcb; cs->pcb.tcp = tpcb;
...@@ -14281,12 +14302,17 @@ void mg_lwip_if_connect_tcp(struct mg_connection *nc, ...@@ -14281,12 +14302,17 @@ void mg_lwip_if_connect_tcp(struct mg_connection *nc,
} }
} }
void mg_lwip_if_connect_tcp(struct mg_connection *nc,
const union socket_address *sa) {
struct mg_lwip_if_connect_tcp_ctx ctx = {.nc = nc, .sa = sa};
tcpip_callback(mg_lwip_if_connect_tcp_tcpip, &ctx);
}
/* /*
* Lwip included in the SDKs for nRF5x chips has different type for the * Lwip included in the SDKs for nRF5x chips has different type for the
* callback of `udp_recv()` * callback of `udp_recv()`
*/ */
#if CS_PLATFORM == CS_P_NRF51 || CS_PLATFORM == CS_P_NRF52 || \ #if LWIP_VERSION >= 0x01050000
CS_PLATFORM == CS_P_STM32
static void mg_lwip_udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p, static void mg_lwip_udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p,
const ip_addr_t *addr, u16_t port) const ip_addr_t *addr, u16_t port)
#else #else
...@@ -14304,7 +14330,11 @@ static void mg_lwip_udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p, ...@@ -14304,7 +14330,11 @@ static void mg_lwip_udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p,
return; return;
} }
union socket_address *sa = (union socket_address *) sap->payload; union socket_address *sa = (union socket_address *) sap->payload;
#if LWIP_VERSION >= 0x01050000
sa->sin.sin_addr.s_addr = ip_2_ip4(addr)->addr;
#else
sa->sin.sin_addr.s_addr = addr->addr; sa->sin.sin_addr.s_addr = addr->addr;
#endif
sa->sin.sin_port = htons(port); sa->sin.sin_port = htons(port);
/* Logic in the recv handler requires that there be exactly one data pbuf. */ /* Logic in the recv handler requires that there be exactly one data pbuf. */
p = pbuf_coalesce(p, PBUF_RAW); p = pbuf_coalesce(p, PBUF_RAW);
...@@ -14353,7 +14383,8 @@ static void mg_lwip_handle_recv_udp(struct mg_connection *nc) { ...@@ -14353,7 +14383,8 @@ static void mg_lwip_handle_recv_udp(struct mg_connection *nc) {
} }
} }
void mg_lwip_if_connect_udp(struct mg_connection *nc) { static void mg_lwip_if_connect_udp_tcpip(void *arg) {
struct mg_connection *nc = (struct mg_connection *) arg;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
struct udp_pcb *upcb = udp_new(); struct udp_pcb *upcb = udp_new();
cs->err = UDP_BIND(upcb, IP_ADDR_ANY, 0 /* any port */); cs->err = UDP_BIND(upcb, IP_ADDR_ANY, 0 /* any port */);
...@@ -14367,6 +14398,10 @@ void mg_lwip_if_connect_udp(struct mg_connection *nc) { ...@@ -14367,6 +14398,10 @@ void mg_lwip_if_connect_udp(struct mg_connection *nc) {
mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc); mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);
} }
void mg_lwip_if_connect_udp(struct mg_connection *nc) {
tcpip_callback(mg_lwip_if_connect_udp_tcpip, nc);
}
void mg_lwip_accept_conn(struct mg_connection *nc, struct tcp_pcb *tpcb) { void mg_lwip_accept_conn(struct mg_connection *nc, struct tcp_pcb *tpcb) {
union socket_address sa; union socket_address sa;
SET_ADDR(&sa, &tpcb->remote_ip); SET_ADDR(&sa, &tpcb->remote_ip);
...@@ -14374,13 +14409,17 @@ void mg_lwip_accept_conn(struct mg_connection *nc, struct tcp_pcb *tpcb) { ...@@ -14374,13 +14409,17 @@ void mg_lwip_accept_conn(struct mg_connection *nc, struct tcp_pcb *tpcb) {
mg_if_accept_tcp_cb(nc, &sa, sizeof(sa.sin)); mg_if_accept_tcp_cb(nc, &sa, sizeof(sa.sin));
} }
static void tcp_close_tcpip(void *arg) {
tcp_close((struct tcp_pcb *) arg);
}
void mg_lwip_handle_accept(struct mg_connection *nc) { void mg_lwip_handle_accept(struct mg_connection *nc) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
#if MG_ENABLE_SSL #if MG_ENABLE_SSL
if (cs->lc->flags & MG_F_SSL) { if (cs->lc->flags & MG_F_SSL) {
if (mg_ssl_if_conn_accept(nc, cs->lc) != MG_SSL_OK) { if (mg_ssl_if_conn_accept(nc, cs->lc) != MG_SSL_OK) {
LOG(LL_ERROR, ("SSL error")); LOG(LL_ERROR, ("SSL error"));
tcp_close(cs->pcb.tcp); tcpip_callback(tcp_close_tcpip, cs->pcb.tcp);
} }
} else } else
#endif #endif
...@@ -14415,7 +14454,16 @@ static err_t mg_lwip_accept_cb(void *arg, struct tcp_pcb *newtpcb, err_t err) { ...@@ -14415,7 +14454,16 @@ static err_t mg_lwip_accept_cb(void *arg, struct tcp_pcb *newtpcb, err_t err) {
return ERR_OK; return ERR_OK;
} }
int mg_lwip_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { struct mg_lwip_if_listen_ctx {
struct mg_connection *nc;
union socket_address *sa;
int ret;
};
static void mg_lwip_if_listen_tcp_tcpip(void *arg) {
struct mg_lwip_if_listen_ctx *ctx = (struct mg_lwip_if_listen_ctx *) arg;
struct mg_connection *nc = ctx->nc;
union socket_address *sa = ctx->sa;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
struct tcp_pcb *tpcb = TCP_NEW(); struct tcp_pcb *tpcb = TCP_NEW();
ip_addr_t *ip = (ip_addr_t *) &sa->sin.sin_addr.s_addr; ip_addr_t *ip = (ip_addr_t *) &sa->sin.sin_addr.s_addr;
...@@ -14424,16 +14472,26 @@ int mg_lwip_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { ...@@ -14424,16 +14472,26 @@ int mg_lwip_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) {
DBG(("%p tcp_bind(%s:%u) = %d", nc, IPADDR_NTOA(ip), port, cs->err)); DBG(("%p tcp_bind(%s:%u) = %d", nc, IPADDR_NTOA(ip), port, cs->err));
if (cs->err != ERR_OK) { if (cs->err != ERR_OK) {
tcp_close(tpcb); tcp_close(tpcb);
return -1; ctx->ret = -1;
return;
} }
tcp_arg(tpcb, nc); tcp_arg(tpcb, nc);
tpcb = tcp_listen(tpcb); tpcb = tcp_listen(tpcb);
cs->pcb.tcp = tpcb; cs->pcb.tcp = tpcb;
tcp_accept(tpcb, mg_lwip_accept_cb); tcp_accept(tpcb, mg_lwip_accept_cb);
return 0; ctx->ret = 0;
} }
int mg_lwip_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { int mg_lwip_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) {
struct mg_lwip_if_listen_ctx ctx = {.nc = nc, .sa = sa};
tcpip_callback(mg_lwip_if_listen_tcp_tcpip, &ctx);
return ctx.ret;
}
static void mg_lwip_if_listen_udp_tcpip(void *arg) {
struct mg_lwip_if_listen_ctx *ctx = (struct mg_lwip_if_listen_ctx *) arg;
struct mg_connection *nc = ctx->nc;
union socket_address *sa = ctx->sa;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
struct udp_pcb *upcb = udp_new(); struct udp_pcb *upcb = udp_new();
ip_addr_t *ip = (ip_addr_t *) &sa->sin.sin_addr.s_addr; ip_addr_t *ip = (ip_addr_t *) &sa->sin.sin_addr.s_addr;
...@@ -14442,24 +14500,43 @@ int mg_lwip_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { ...@@ -14442,24 +14500,43 @@ int mg_lwip_if_listen_udp(struct mg_connection *nc, union socket_address *sa) {
DBG(("%p udb_bind(%s:%u) = %d", nc, IPADDR_NTOA(ip), port, cs->err)); DBG(("%p udb_bind(%s:%u) = %d", nc, IPADDR_NTOA(ip), port, cs->err));
if (cs->err != ERR_OK) { if (cs->err != ERR_OK) {
udp_remove(upcb); udp_remove(upcb);
return -1; ctx->ret = -1;
} else {
udp_recv(upcb, mg_lwip_udp_recv_cb, nc);
cs->pcb.udp = upcb;
ctx->ret = 0;
} }
udp_recv(upcb, mg_lwip_udp_recv_cb, nc);
cs->pcb.udp = upcb;
return 0;
} }
int mg_lwip_tcp_write(struct mg_connection *nc, const void *data, int mg_lwip_if_listen_udp(struct mg_connection *nc, union socket_address *sa) {
uint16_t len) { struct mg_lwip_if_listen_ctx ctx = {.nc = nc, .sa = sa};
tcpip_callback(mg_lwip_if_listen_udp_tcpip, &ctx);
return ctx.ret;
}
struct mg_lwip_tcp_write_ctx {
struct mg_connection *nc;
const void *data;
uint16_t len;
int ret;
};
static void tcp_output_tcpip(void *arg) {
tcp_output((struct tcp_pcb *) arg);
}
static void mg_lwip_tcp_write_tcpip(void *arg) {
struct mg_lwip_tcp_write_ctx *ctx = (struct mg_lwip_tcp_write_ctx *) arg;
struct mg_connection *nc = ctx->nc;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
struct tcp_pcb *tpcb = cs->pcb.tcp; struct tcp_pcb *tpcb = cs->pcb.tcp;
if (tpcb == NULL) return -1; uint16_t len = MIN(tpcb->mss, MIN(ctx->len, tpcb->snd_buf));
len = MIN(tpcb->mss, MIN(len, tpcb->snd_buf));
if (len == 0) { if (len == 0) {
DBG(("%p no buf avail %u %u %u %p %p", tpcb, tpcb->acked, tpcb->snd_buf, DBG(("%p no buf avail %u %u %u %p %p", tpcb, tpcb->acked, tpcb->snd_buf,
tpcb->snd_queuelen, tpcb->unsent, tpcb->unacked)); tpcb->snd_queuelen, tpcb->unsent, tpcb->unacked));
tcp_output(tpcb); tcpip_callback(tcp_output_tcpip, tpcb);
return 0; ctx->ret = 0;
return;
} }
/* /*
* On ESP8266 we only allow one TCP segment in flight at any given time. * On ESP8266 we only allow one TCP segment in flight at any given time.
...@@ -14469,22 +14546,49 @@ int mg_lwip_tcp_write(struct mg_connection *nc, const void *data, ...@@ -14469,22 +14546,49 @@ int mg_lwip_tcp_write(struct mg_connection *nc, const void *data,
*/ */
#if CS_PLATFORM == CS_P_ESP8266 #if CS_PLATFORM == CS_P_ESP8266
if (tpcb->unacked != NULL) { if (tpcb->unacked != NULL) {
return 0; ctx->ret = 0;
return;
} }
if (tpcb->unsent != NULL) { if (tpcb->unsent != NULL) {
len = MIN(len, (TCP_MSS - tpcb->unsent->len)); len = MIN(len, (TCP_MSS - tpcb->unsent->len));
} }
#endif #endif
cs->err = tcp_write(tpcb, data, len, TCP_WRITE_FLAG_COPY); cs->err = tcp_write(tpcb, ctx->data, len, TCP_WRITE_FLAG_COPY);
DBG(("%p tcp_write %u = %d", tpcb, len, cs->err)); DBG(("%p tcp_write %u = %d", tpcb, len, cs->err));
if (cs->err != ERR_OK) { if (cs->err != ERR_OK) {
/* /*
* We ignore ERR_MEM because memory will be freed up when the data is sent * We ignore ERR_MEM because memory will be freed up when the data is sent
* and we'll retry. * and we'll retry.
*/ */
return (cs->err == ERR_MEM ? 0 : -1); ctx->ret = (cs->err == ERR_MEM ? 0 : -1);
return;
} }
return len; ctx->ret = len;
}
static int mg_lwip_tcp_write(struct mg_connection *nc, const void *data,
uint16_t len) {
struct mg_lwip_tcp_write_ctx ctx = {.nc = nc, .data = data, .len = len};
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
struct tcp_pcb *tpcb = cs->pcb.tcp;
if (tpcb == NULL) {
return -1;
}
tcpip_callback(mg_lwip_tcp_write_tcpip, &ctx);
return ctx.ret;
}
struct udp_sendto_ctx {
struct udp_pcb *upcb;
struct pbuf *p;
ip_addr_t *ip;
uint16_t port;
int ret;
};
static void udp_sendto_tcpip(void *arg) {
struct udp_sendto_ctx *ctx = (struct udp_sendto_ctx *) arg;
ctx->ret = udp_sendto(ctx->upcb, ctx->p, ctx->ip, ctx->port);
} }
static int mg_lwip_udp_send(struct mg_connection *nc, const void *data, static int mg_lwip_udp_send(struct mg_connection *nc, const void *data,
...@@ -14508,7 +14612,9 @@ static int mg_lwip_udp_send(struct mg_connection *nc, const void *data, ...@@ -14508,7 +14612,9 @@ static int mg_lwip_udp_send(struct mg_connection *nc, const void *data,
return 0; return 0;
} }
memcpy(p->payload, data, len); memcpy(p->payload, data, len);
cs->err = udp_sendto(upcb, p, (ip_addr_t *) ip, port); struct udp_sendto_ctx ctx = {.upcb = upcb, .p = p, .ip = ip, .port = port};
tcpip_callback(udp_sendto_tcpip, &ctx);
cs->err = ctx.ret;
DBG(("%p udp_sendto = %d", nc, cs->err)); DBG(("%p udp_sendto = %d", nc, cs->err));
pbuf_free(p); pbuf_free(p);
return (cs->err == ERR_OK ? len : -1); return (cs->err == ERR_OK ? len : -1);
...@@ -14544,6 +14650,16 @@ void mg_lwip_if_udp_send(struct mg_connection *nc, const void *buf, ...@@ -14544,6 +14650,16 @@ void mg_lwip_if_udp_send(struct mg_connection *nc, const void *buf,
mg_lwip_mgr_schedule_poll(nc->mgr); mg_lwip_mgr_schedule_poll(nc->mgr);
} }
struct tcp_recved_ctx {
struct tcp_pcb *tpcb;
size_t len;
};
void tcp_recved_tcpip(void *arg) {
struct tcp_recved_ctx *ctx = (struct tcp_recved_ctx *) arg;
tcp_recved(ctx->tpcb, ctx->len);
}
void mg_lwip_if_recved(struct mg_connection *nc, size_t len) { void mg_lwip_if_recved(struct mg_connection *nc, size_t len) {
if (nc->flags & MG_F_UDP) return; if (nc->flags & MG_F_UDP) return;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
...@@ -14552,14 +14668,16 @@ void mg_lwip_if_recved(struct mg_connection *nc, size_t len) { ...@@ -14552,14 +14668,16 @@ void mg_lwip_if_recved(struct mg_connection *nc, size_t len) {
return; return;
} }
DBG(("%p %p %u", nc, cs->pcb.tcp, len)); DBG(("%p %p %u", nc, cs->pcb.tcp, len));
/* Currently SSL acknowledges data immediately. struct tcp_recved_ctx ctx = {.tpcb = cs->pcb.tcp, .len = len};
* TODO(rojer): Find a way to propagate mg_lwip_if_recved. */
#if MG_ENABLE_SSL #if MG_ENABLE_SSL
if (!(nc->flags & MG_F_SSL)) { if (!(nc->flags & MG_F_SSL)) {
tcp_recved(cs->pcb.tcp, len); tcpip_callback(tcp_recved_tcpip, &ctx);
} else {
/* Currently SSL acknowledges data immediately.
* TODO(rojer): Find a way to propagate mg_lwip_if_recved. */
} }
#else #else
tcp_recved(cs->pcb.tcp, len); tcpip_callback(tcp_recved_tcpip, &ctx);
#endif #endif
mbuf_trim(&nc->recv_mbuf); mbuf_trim(&nc->recv_mbuf);
} }
...@@ -14573,6 +14691,10 @@ int mg_lwip_if_create_conn(struct mg_connection *nc) { ...@@ -14573,6 +14691,10 @@ int mg_lwip_if_create_conn(struct mg_connection *nc) {
return 1; return 1;
} }
static void udp_remove_tcpip(void *arg) {
udp_remove((struct udp_pcb *) arg);
}
void mg_lwip_if_destroy_conn(struct mg_connection *nc) { void mg_lwip_if_destroy_conn(struct mg_connection *nc) {
if (nc->sock == INVALID_SOCKET) return; if (nc->sock == INVALID_SOCKET) return;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
...@@ -14582,7 +14704,7 @@ void mg_lwip_if_destroy_conn(struct mg_connection *nc) { ...@@ -14582,7 +14704,7 @@ void mg_lwip_if_destroy_conn(struct mg_connection *nc) {
tcp_arg(tpcb, NULL); tcp_arg(tpcb, NULL);
DBG(("%p tcp_close %p", nc, tpcb)); DBG(("%p tcp_close %p", nc, tpcb));
tcp_arg(tpcb, NULL); tcp_arg(tpcb, NULL);
tcp_close(tpcb); tcpip_callback(tcp_close_tcpip, tpcb);
} }
while (cs->rx_chain != NULL) { while (cs->rx_chain != NULL) {
struct pbuf *seg = cs->rx_chain; struct pbuf *seg = cs->rx_chain;
...@@ -14596,7 +14718,7 @@ void mg_lwip_if_destroy_conn(struct mg_connection *nc) { ...@@ -14596,7 +14718,7 @@ void mg_lwip_if_destroy_conn(struct mg_connection *nc) {
struct udp_pcb *upcb = cs->pcb.udp; struct udp_pcb *upcb = cs->pcb.udp;
if (upcb != NULL) { if (upcb != NULL) {
DBG(("%p udp_remove %p", nc, upcb)); DBG(("%p udp_remove %p", nc, upcb));
udp_remove(upcb); tcpip_callback(udp_remove_tcpip, upcb);
} }
memset(cs, 0, sizeof(*cs)); memset(cs, 0, sizeof(*cs));
MG_FREE(cs); MG_FREE(cs);
...@@ -14830,7 +14952,7 @@ time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) { ...@@ -14830,7 +14952,7 @@ time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) {
if (nc->sock != INVALID_SOCKET && if (nc->sock != INVALID_SOCKET &&
!(nc->flags & (MG_F_UDP | MG_F_LISTENING)) && cs->pcb.tcp != NULL && !(nc->flags & (MG_F_UDP | MG_F_LISTENING)) && cs->pcb.tcp != NULL &&
cs->pcb.tcp->unsent != NULL) { cs->pcb.tcp->unsent != NULL) {
tcp_output(cs->pcb.tcp); tcpip_callback(tcp_output_tcpip, cs->pcb.tcp);
} }
if (nc->ev_timer_time > 0) { if (nc->ev_timer_time > 0) {
if (num_timers == 0 || nc->ev_timer_time < min_timer) { if (num_timers == 0 || nc->ev_timer_time < min_timer) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment