mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-17 17:10:03 +00:00
Add non-blocking support for connect (partly from patch #6860) plus many cleanups in socket & netconn API
This commit is contained in:
parent
1dd8300e69
commit
e58f4c567a
@ -19,6 +19,11 @@ HISTORY
|
|||||||
|
|
||||||
++ New features:
|
++ New features:
|
||||||
|
|
||||||
|
2010-01-29: Simon Goldschmidt (patch by Laura Garrett)
|
||||||
|
* api.h, sockets.h, err.h, api_lib.c, api_msg.c, sockets.c, err.c:
|
||||||
|
Add non-blocking support for connect (partly from patch #6860),
|
||||||
|
plus many cleanups in socket & netconn API.
|
||||||
|
|
||||||
2010-01-27: Simon Goldschmidt
|
2010-01-27: Simon Goldschmidt
|
||||||
* opt.h, tcp.h, init.c, api_msg.c: Added TCP_SNDQUEUELOWAT corresponding
|
* opt.h, tcp.h, init.c, api_msg.c: Added TCP_SNDQUEUELOWAT corresponding
|
||||||
to TCP_SNDLOWAT and added tcp_sndqueuelen() - this fixes bug #28605
|
to TCP_SNDLOWAT and added tcp_sndqueuelen() - this fixes bug #28605
|
||||||
|
@ -111,7 +111,6 @@ netconn_delete(struct netconn *conn)
|
|||||||
msg.msg.conn = conn;
|
msg.msg.conn = conn;
|
||||||
tcpip_apimsg(&msg);
|
tcpip_apimsg(&msg);
|
||||||
|
|
||||||
conn->pcb.tcp = NULL;
|
|
||||||
netconn_free(conn);
|
netconn_free(conn);
|
||||||
|
|
||||||
/* don't care for return value of do_delconn since it only calls void functions */
|
/* don't care for return value of do_delconn since it only calls void functions */
|
||||||
@ -493,6 +492,9 @@ netconn_write(struct netconn *conn, const void *dataptr, size_t size, u8_t apifl
|
|||||||
|
|
||||||
LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||||
LWIP_ERROR("netconn_write: invalid conn->type", (conn->type == NETCONN_TCP), return ERR_VAL;);
|
LWIP_ERROR("netconn_write: invalid conn->type", (conn->type == NETCONN_TCP), return ERR_VAL;);
|
||||||
|
if (size == 0) {
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
msg.function = do_write;
|
msg.function = do_write;
|
||||||
msg.msg.conn = conn;
|
msg.msg.conn = conn;
|
||||||
|
@ -98,7 +98,8 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(q != NULL) {
|
if (q != NULL) {
|
||||||
|
u16_t len;
|
||||||
buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
|
buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
pbuf_free(q);
|
pbuf_free(q);
|
||||||
@ -110,13 +111,14 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
|
|||||||
buf->addr = &(((struct ip_hdr*)(q->payload))->src);
|
buf->addr = &(((struct ip_hdr*)(q->payload))->src);
|
||||||
buf->port = pcb->protocol;
|
buf->port = pcb->protocol;
|
||||||
|
|
||||||
|
len = q->tot_len;
|
||||||
if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
|
if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
|
||||||
netbuf_delete(buf);
|
netbuf_delete(buf);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
SYS_ARCH_INC(conn->recv_avail, q->tot_len);
|
SYS_ARCH_INC(conn->recv_avail, len);
|
||||||
/* Register event with callback */
|
/* Register event with callback */
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, q->tot_len);
|
API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,6 +140,7 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
|||||||
{
|
{
|
||||||
struct netbuf *buf;
|
struct netbuf *buf;
|
||||||
struct netconn *conn;
|
struct netconn *conn;
|
||||||
|
u16_t len;
|
||||||
#if LWIP_SO_RCVBUF
|
#if LWIP_SO_RCVBUF
|
||||||
int recv_avail;
|
int recv_avail;
|
||||||
#endif /* LWIP_SO_RCVBUF */
|
#endif /* LWIP_SO_RCVBUF */
|
||||||
@ -179,13 +182,14 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
|||||||
#endif /* LWIP_NETBUF_RECVINFO */
|
#endif /* LWIP_NETBUF_RECVINFO */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
len = p->tot_len;
|
||||||
if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
|
if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
|
||||||
netbuf_delete(buf);
|
netbuf_delete(buf);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
SYS_ARCH_INC(conn->recv_avail, p->tot_len);
|
SYS_ARCH_INC(conn->recv_avail, len);
|
||||||
/* Register event with callback */
|
/* Register event with callback */
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
|
API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* LWIP_UDP */
|
#endif /* LWIP_UDP */
|
||||||
@ -220,20 +224,24 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
|
|||||||
}
|
}
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
/* Unlike for UDP or RAW pcbs, don't check for available space
|
||||||
|
using recv_avail since that could break the connection
|
||||||
|
(data is already ACKed) */
|
||||||
|
|
||||||
/* don't overwrite fatal errors! */
|
/* don't overwrite fatal errors! */
|
||||||
NETCONN_SET_SAFE_ERR(conn, err);
|
NETCONN_SET_SAFE_ERR(conn, err);
|
||||||
|
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
len = p->tot_len;
|
len = p->tot_len;
|
||||||
SYS_ARCH_INC(conn->recv_avail, len);
|
|
||||||
} else {
|
} else {
|
||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sys_mbox_trypost(conn->recvmbox, p) != ERR_OK) {
|
if (sys_mbox_trypost(conn->recvmbox, p) != ERR_OK) {
|
||||||
|
/* don't deallocate p: it is presented to us later again from tcp_fasttmr! */
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
} else {
|
} else {
|
||||||
|
SYS_ARCH_INC(conn->recv_avail, len);
|
||||||
/* Register event with callback */
|
/* Register event with callback */
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
|
API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
|
||||||
}
|
}
|
||||||
@ -265,6 +273,7 @@ poll_tcp(void *arg, struct tcp_pcb *pcb)
|
|||||||
} else if (conn->state == NETCONN_CLOSE) {
|
} else if (conn->state == NETCONN_CLOSE) {
|
||||||
do_close_internal(conn);
|
do_close_internal(conn);
|
||||||
}
|
}
|
||||||
|
/* @todo: implement connect timeout here? */
|
||||||
|
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
@ -285,7 +294,6 @@ sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
|
|||||||
LWIP_ASSERT("conn != NULL", (conn != NULL));
|
LWIP_ASSERT("conn != NULL", (conn != NULL));
|
||||||
|
|
||||||
if (conn->state == NETCONN_WRITE) {
|
if (conn->state == NETCONN_WRITE) {
|
||||||
LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL);
|
|
||||||
do_writemore(conn);
|
do_writemore(conn);
|
||||||
} else if (conn->state == NETCONN_CLOSE) {
|
} else if (conn->state == NETCONN_CLOSE) {
|
||||||
do_close_internal(conn);
|
do_close_internal(conn);
|
||||||
@ -327,7 +335,7 @@ err_tcp(void *arg, err_t err)
|
|||||||
conn->last_err = err;
|
conn->last_err = err;
|
||||||
SYS_ARCH_UNPROTECT(lev);
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
|
|
||||||
/* API_EVENT might call tcp_tmr, so reset conn->state now */
|
/* reset conn->state now before waking up other threads */
|
||||||
old_state = conn->state;
|
old_state = conn->state;
|
||||||
conn->state = NETCONN_NONE;
|
conn->state = NETCONN_NONE;
|
||||||
|
|
||||||
@ -347,13 +355,17 @@ err_tcp(void *arg, err_t err)
|
|||||||
(old_state == NETCONN_CONNECT)) {
|
(old_state == NETCONN_CONNECT)) {
|
||||||
/* calling do_writemore/do_close_internal is not necessary
|
/* calling do_writemore/do_close_internal is not necessary
|
||||||
since the pcb has already been deleted! */
|
since the pcb has already been deleted! */
|
||||||
|
int was_nonblocking_connect = conn->in_non_blocking_connect;
|
||||||
|
conn->in_non_blocking_connect = 0;
|
||||||
|
|
||||||
/* set error return code */
|
if (!was_nonblocking_connect) {
|
||||||
LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
|
/* set error return code */
|
||||||
conn->current_msg->err = err;
|
LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
|
||||||
conn->current_msg = NULL;
|
conn->current_msg->err = err;
|
||||||
/* wake up the waiting task */
|
conn->current_msg = NULL;
|
||||||
sys_sem_signal(conn->op_completed);
|
/* wake up the waiting task */
|
||||||
|
sys_sem_signal(conn->op_completed);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL);
|
LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL);
|
||||||
}
|
}
|
||||||
@ -415,7 +427,7 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
|
|||||||
newconn->last_err = err;
|
newconn->last_err = err;
|
||||||
|
|
||||||
if (sys_mbox_trypost(conn->acceptmbox, newconn) != ERR_OK) {
|
if (sys_mbox_trypost(conn->acceptmbox, newconn) != ERR_OK) {
|
||||||
/* When returning != ERR_OK, the connection is aborted in tcp_process(),
|
/* When returning != ERR_OK, the pcb is aborted in tcp_process(),
|
||||||
so do nothing here! */
|
so do nothing here! */
|
||||||
newconn->pcb.tcp = NULL;
|
newconn->pcb.tcp = NULL;
|
||||||
/* no need to drain since we know the recvmbox is empty. */
|
/* no need to drain since we know the recvmbox is empty. */
|
||||||
@ -591,6 +603,8 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
|
|||||||
#if LWIP_SO_RCVBUF
|
#if LWIP_SO_RCVBUF
|
||||||
conn->recv_bufsize = RECV_BUFSIZE_DEFAULT;
|
conn->recv_bufsize = RECV_BUFSIZE_DEFAULT;
|
||||||
#endif /* LWIP_SO_RCVBUF */
|
#endif /* LWIP_SO_RCVBUF */
|
||||||
|
conn->non_blocking = 0;
|
||||||
|
conn->in_non_blocking_connect = 0;
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,8 +721,8 @@ do_close_internal(struct netconn *conn)
|
|||||||
conn->state = NETCONN_NONE;
|
conn->state = NETCONN_NONE;
|
||||||
/* Set back some callback pointers as conn is going away */
|
/* Set back some callback pointers as conn is going away */
|
||||||
conn->pcb.tcp = NULL;
|
conn->pcb.tcp = NULL;
|
||||||
/* Trigger select() in socket layer. This send should something else so the
|
/* @todo: this lets select make the socket readable and writable,
|
||||||
errorfd is set, not the read and write fd! */
|
which is wrong! errfd instead? */
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
||||||
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
||||||
/* wake up the application task */
|
/* wake up the application task */
|
||||||
@ -736,45 +750,52 @@ do_close_internal(struct netconn *conn)
|
|||||||
void
|
void
|
||||||
do_delconn(struct api_msg_msg *msg)
|
do_delconn(struct api_msg_msg *msg)
|
||||||
{
|
{
|
||||||
/* Drain and delete mboxes */
|
/* @todo TCP: abort running write/connect? */
|
||||||
netconn_drain(msg->conn);
|
if ((msg->conn->state != NETCONN_NONE) && (msg->conn->state != NETCONN_LISTEN)) {
|
||||||
|
/* this only happens for TCP netconns */
|
||||||
|
LWIP_ASSERT("msg->conn->type == NETCONN_TCP", msg->conn->type == NETCONN_TCP);
|
||||||
|
msg->err = ERR_INPROGRESS;
|
||||||
|
} else {
|
||||||
|
/* Drain and delete mboxes */
|
||||||
|
netconn_drain(msg->conn);
|
||||||
|
|
||||||
if (msg->conn->pcb.tcp != NULL) {
|
if (msg->conn->pcb.tcp != NULL) {
|
||||||
|
|
||||||
switch (NETCONNTYPE_GROUP(msg->conn->type)) {
|
switch (NETCONNTYPE_GROUP(msg->conn->type)) {
|
||||||
#if LWIP_RAW
|
#if LWIP_RAW
|
||||||
case NETCONN_RAW:
|
case NETCONN_RAW:
|
||||||
raw_remove(msg->conn->pcb.raw);
|
raw_remove(msg->conn->pcb.raw);
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_RAW */
|
#endif /* LWIP_RAW */
|
||||||
#if LWIP_UDP
|
#if LWIP_UDP
|
||||||
case NETCONN_UDP:
|
case NETCONN_UDP:
|
||||||
msg->conn->pcb.udp->recv_arg = NULL;
|
msg->conn->pcb.udp->recv_arg = NULL;
|
||||||
udp_remove(msg->conn->pcb.udp);
|
udp_remove(msg->conn->pcb.udp);
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_UDP */
|
#endif /* LWIP_UDP */
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
case NETCONN_TCP:
|
case NETCONN_TCP:
|
||||||
LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
|
LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
|
||||||
msg->conn->write_offset == 0);
|
msg->conn->write_offset == 0);
|
||||||
msg->conn->state = NETCONN_CLOSE;
|
msg->conn->state = NETCONN_CLOSE;
|
||||||
msg->conn->current_msg = msg;
|
msg->conn->current_msg = msg;
|
||||||
do_close_internal(msg->conn);
|
do_close_internal(msg->conn);
|
||||||
/* API_EVENT is called inside do_close_internal, before releasing
|
/* API_EVENT is called inside do_close_internal, before releasing
|
||||||
the application thread, so we can return at this point! */
|
the application thread, so we can return at this point! */
|
||||||
return;
|
return;
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
msg->conn->pcb.tcp = NULL;
|
||||||
}
|
}
|
||||||
|
/* tcp netconns don't come here! */
|
||||||
|
|
||||||
|
/* @todo: this lets select make the socket readable and writable,
|
||||||
|
which is wrong! errfd instead? */
|
||||||
|
API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0);
|
||||||
|
API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0);
|
||||||
}
|
}
|
||||||
/* tcp netconns don't come here! */
|
|
||||||
|
|
||||||
/* Trigger select() in socket layer. This send should something else so the
|
|
||||||
errorfd is set, not the read and write fd! */
|
|
||||||
API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0);
|
|
||||||
API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0);
|
|
||||||
|
|
||||||
if (msg->conn->op_completed != SYS_SEM_NULL) {
|
if (msg->conn->op_completed != SYS_SEM_NULL) {
|
||||||
sys_sem_signal(msg->conn->op_completed);
|
sys_sem_signal(msg->conn->op_completed);
|
||||||
}
|
}
|
||||||
@ -830,6 +851,7 @@ static err_t
|
|||||||
do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
|
do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
|
||||||
{
|
{
|
||||||
struct netconn *conn;
|
struct netconn *conn;
|
||||||
|
int was_blocking;
|
||||||
|
|
||||||
LWIP_UNUSED_ARG(pcb);
|
LWIP_UNUSED_ARG(pcb);
|
||||||
|
|
||||||
@ -840,15 +862,32 @@ do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT);
|
LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT);
|
||||||
LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
|
LWIP_ASSERT("(conn->current_msg != NULL) || conn->in_non_blocking_connect",
|
||||||
|
(conn->current_msg != NULL) || conn->in_non_blocking_connect);
|
||||||
|
|
||||||
conn->current_msg->err = err;
|
if (conn->current_msg != NULL) {
|
||||||
|
conn->current_msg->err = err;
|
||||||
|
}
|
||||||
if ((conn->type == NETCONN_TCP) && (err == ERR_OK)) {
|
if ((conn->type == NETCONN_TCP) && (err == ERR_OK)) {
|
||||||
setup_tcp(conn);
|
setup_tcp(conn);
|
||||||
}
|
}
|
||||||
|
was_blocking = !conn->in_non_blocking_connect;
|
||||||
|
conn->in_non_blocking_connect = 0;
|
||||||
conn->current_msg = NULL;
|
conn->current_msg = NULL;
|
||||||
conn->state = NETCONN_NONE;
|
conn->state = NETCONN_NONE;
|
||||||
sys_sem_signal(conn->op_completed);
|
if (!was_blocking) {
|
||||||
|
SYS_ARCH_DECL_PROTECT(lev);
|
||||||
|
SYS_ARCH_PROTECT(lev);
|
||||||
|
if (conn->last_err == ERR_INPROGRESS) {
|
||||||
|
conn->last_err = ERR_OK;
|
||||||
|
}
|
||||||
|
SYS_ARCH_UNPROTECT(lev);
|
||||||
|
}
|
||||||
|
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
||||||
|
|
||||||
|
if (was_blocking) {
|
||||||
|
sys_sem_signal(conn->op_completed);
|
||||||
|
}
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
@ -866,44 +905,48 @@ do_connect(struct api_msg_msg *msg)
|
|||||||
if (msg->conn->pcb.tcp == NULL) {
|
if (msg->conn->pcb.tcp == NULL) {
|
||||||
/* This may happen when calling netconn_connect() a second time */
|
/* This may happen when calling netconn_connect() a second time */
|
||||||
msg->err = ERR_CLSD;
|
msg->err = ERR_CLSD;
|
||||||
sys_sem_signal(msg->conn->op_completed);
|
} else {
|
||||||
return;
|
switch (NETCONNTYPE_GROUP(msg->conn->type)) {
|
||||||
}
|
|
||||||
|
|
||||||
switch (NETCONNTYPE_GROUP(msg->conn->type)) {
|
|
||||||
#if LWIP_RAW
|
#if LWIP_RAW
|
||||||
case NETCONN_RAW:
|
case NETCONN_RAW:
|
||||||
msg->err = raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
|
msg->err = raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
|
||||||
sys_sem_signal(msg->conn->op_completed);
|
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_RAW */
|
#endif /* LWIP_RAW */
|
||||||
#if LWIP_UDP
|
#if LWIP_UDP
|
||||||
case NETCONN_UDP:
|
case NETCONN_UDP:
|
||||||
msg->err = udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
|
msg->err = udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
|
||||||
sys_sem_signal(msg->conn->op_completed);
|
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_UDP */
|
#endif /* LWIP_UDP */
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
case NETCONN_TCP:
|
case NETCONN_TCP:
|
||||||
setup_tcp(msg->conn);
|
/* Prevent connect while doing any other action. */
|
||||||
msg->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port,
|
if (msg->conn->state != NETCONN_NONE) {
|
||||||
do_connected);
|
msg->err = ERR_ISCONN;
|
||||||
/* sys_sem_signal() is called from do_connected (or err_tcp()),
|
|
||||||
* when the connection is established! */
|
|
||||||
if (msg->err == ERR_OK) {
|
|
||||||
msg->conn->state = NETCONN_CONNECT;
|
|
||||||
msg->conn->current_msg = msg;
|
|
||||||
} else {
|
} else {
|
||||||
/* tcp_connect failed, so do_connected will not be called: return now */
|
setup_tcp(msg->conn);
|
||||||
sys_sem_signal(msg->conn->op_completed);
|
msg->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr,
|
||||||
|
msg->msg.bc.port, do_connected);
|
||||||
|
if (msg->err == ERR_OK) {
|
||||||
|
msg->conn->state = NETCONN_CONNECT;
|
||||||
|
msg->conn->in_non_blocking_connect = msg->conn->non_blocking;
|
||||||
|
if (msg->conn->non_blocking) {
|
||||||
|
msg->err = ERR_INPROGRESS;
|
||||||
|
} else {
|
||||||
|
msg->conn->current_msg = msg;
|
||||||
|
/* sys_sem_signal() is called from do_connected (or err_tcp()),
|
||||||
|
* when the connection is established! */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
default:
|
default:
|
||||||
LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL;
|
LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL; }while(0));
|
||||||
sys_sem_signal(msg->conn->op_completed); }while(0));
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
sys_sem_signal(msg->conn->op_completed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -944,13 +987,14 @@ do_listen(struct api_msg_msg *msg)
|
|||||||
msg->err = ERR_CONN;
|
msg->err = ERR_CONN;
|
||||||
if (msg->conn->pcb.tcp != NULL) {
|
if (msg->conn->pcb.tcp != NULL) {
|
||||||
if (msg->conn->type == NETCONN_TCP) {
|
if (msg->conn->type == NETCONN_TCP) {
|
||||||
if (msg->conn->pcb.tcp->state == CLOSED) {
|
if (msg->conn->state == NETCONN_NONE) {
|
||||||
#if TCP_LISTEN_BACKLOG
|
#if TCP_LISTEN_BACKLOG
|
||||||
struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
|
struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
|
||||||
#else /* TCP_LISTEN_BACKLOG */
|
#else /* TCP_LISTEN_BACKLOG */
|
||||||
struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp);
|
struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp);
|
||||||
#endif /* TCP_LISTEN_BACKLOG */
|
#endif /* TCP_LISTEN_BACKLOG */
|
||||||
if (lpcb == NULL) {
|
if (lpcb == NULL) {
|
||||||
|
/* in this case, the old pcb is still allocated */
|
||||||
msg->err = ERR_MEM;
|
msg->err = ERR_MEM;
|
||||||
} else {
|
} else {
|
||||||
/* delete the recvmbox and allocate the acceptmbox */
|
/* delete the recvmbox and allocate the acceptmbox */
|
||||||
@ -970,6 +1014,10 @@ do_listen(struct api_msg_msg *msg)
|
|||||||
msg->conn->pcb.tcp = lpcb;
|
msg->conn->pcb.tcp = lpcb;
|
||||||
tcp_arg(msg->conn->pcb.tcp, msg->conn);
|
tcp_arg(msg->conn->pcb.tcp, msg->conn);
|
||||||
tcp_accept(msg->conn->pcb.tcp, accept_function);
|
tcp_accept(msg->conn->pcb.tcp, accept_function);
|
||||||
|
} else {
|
||||||
|
/* since the old pcb is already deallocated, free lpcb now */
|
||||||
|
tcp_close(lpcb);
|
||||||
|
msg->conn->pcb.tcp = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1072,6 +1120,9 @@ do_writemore(struct netconn *conn)
|
|||||||
LWIP_ASSERT("conn != NULL", conn != NULL);
|
LWIP_ASSERT("conn != NULL", conn != NULL);
|
||||||
LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE));
|
LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE));
|
||||||
LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
|
LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
|
||||||
|
LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL);
|
||||||
|
LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len",
|
||||||
|
conn->write_offset < conn->current_msg->msg.w.len);
|
||||||
|
|
||||||
dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset;
|
dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset;
|
||||||
diff = conn->current_msg->msg.w.len - conn->write_offset;
|
diff = conn->current_msg->msg.w.len - conn->write_offset;
|
||||||
@ -1094,29 +1145,31 @@ do_writemore(struct netconn *conn)
|
|||||||
|
|
||||||
err = tcp_write(conn->pcb.tcp, dataptr, len, conn->current_msg->msg.w.apiflags);
|
err = tcp_write(conn->pcb.tcp, dataptr, len, conn->current_msg->msg.w.apiflags);
|
||||||
LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len));
|
LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len));
|
||||||
|
|
||||||
|
/* if OK or memory error, check available space */
|
||||||
|
if (((err == ERR_OK) || (err == ERR_MEM)) &&
|
||||||
|
((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) ||
|
||||||
|
(tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT))) {
|
||||||
|
/* The queued byte- or pbuf-count exceeds the configured low-water limit,
|
||||||
|
let select mark this pcb as non-writable. */
|
||||||
|
API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
|
||||||
|
}
|
||||||
|
|
||||||
if (err == ERR_OK) {
|
if (err == ERR_OK) {
|
||||||
conn->write_offset += len;
|
conn->write_offset += len;
|
||||||
if (conn->write_offset == conn->current_msg->msg.w.len) {
|
if (conn->write_offset == conn->current_msg->msg.w.len) {
|
||||||
/* everything was written */
|
/* everything was written */
|
||||||
write_finished = 1;
|
write_finished = 1;
|
||||||
conn->write_offset = 0;
|
conn->write_offset = 0;
|
||||||
/* API_EVENT might call tcp_tmr, so reset conn->state now */
|
|
||||||
conn->state = NETCONN_NONE;
|
|
||||||
}
|
|
||||||
err = tcp_output_nagle(conn->pcb.tcp);
|
|
||||||
/* If the queued byte- or pbuf-count exceeds the configured low-water limit,
|
|
||||||
let select mark this pcb as non-writable. */
|
|
||||||
if ((err == ERR_OK) && (tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) ||
|
|
||||||
(tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) {
|
|
||||||
API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
|
|
||||||
}
|
}
|
||||||
|
tcp_output_nagle(conn->pcb.tcp);
|
||||||
} else if (err == ERR_MEM) {
|
} else if (err == ERR_MEM) {
|
||||||
/* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called
|
/* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called
|
||||||
we do NOT return to the application thread, since ERR_MEM is
|
we do NOT return to the application thread, since ERR_MEM is
|
||||||
only a temporary error! */
|
only a temporary error! */
|
||||||
|
|
||||||
/* tcp_enqueue returned ERR_MEM, try tcp_output anyway */
|
/* tcp_enqueue returned ERR_MEM, try tcp_output anyway */
|
||||||
err = tcp_output(conn->pcb.tcp);
|
tcp_output(conn->pcb.tcp);
|
||||||
|
|
||||||
#if LWIP_TCPIP_CORE_LOCKING
|
#if LWIP_TCPIP_CORE_LOCKING
|
||||||
conn->write_delayed = 1;
|
conn->write_delayed = 1;
|
||||||
@ -1162,11 +1215,14 @@ do_write(struct api_msg_msg *msg)
|
|||||||
} else {
|
} else {
|
||||||
if (msg->conn->type == NETCONN_TCP) {
|
if (msg->conn->type == NETCONN_TCP) {
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
if (msg->conn->pcb.tcp != NULL) {
|
if (msg->conn->state != NETCONN_NONE) {
|
||||||
|
msg->err = ERR_INPROGRESS;
|
||||||
|
} else if (msg->conn->pcb.tcp != NULL) {
|
||||||
msg->conn->state = NETCONN_WRITE;
|
msg->conn->state = NETCONN_WRITE;
|
||||||
/* set all the variables used by do_writemore */
|
/* set all the variables used by do_writemore */
|
||||||
LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
|
LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
|
||||||
msg->conn->write_offset == 0);
|
msg->conn->write_offset == 0);
|
||||||
|
LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0);
|
||||||
msg->conn->current_msg = msg;
|
msg->conn->current_msg = msg;
|
||||||
msg->conn->write_offset = 0;
|
msg->conn->write_offset = 0;
|
||||||
#if LWIP_TCPIP_CORE_LOCKING
|
#if LWIP_TCPIP_CORE_LOCKING
|
||||||
@ -1258,7 +1314,13 @@ void
|
|||||||
do_close(struct api_msg_msg *msg)
|
do_close(struct api_msg_msg *msg)
|
||||||
{
|
{
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
|
/* @todo: abort running write/connect? */
|
||||||
|
if ((msg->conn->state != NETCONN_NONE) && (msg->conn->state != NETCONN_LISTEN)) {
|
||||||
|
/* this only happens for TCP netconns */
|
||||||
|
LWIP_ASSERT("msg->conn->type == NETCONN_TCP", msg->conn->type == NETCONN_TCP);
|
||||||
|
msg->err = ERR_INPROGRESS;
|
||||||
|
} else if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
|
||||||
|
/* Drain and delete mboxes */
|
||||||
netconn_drain(msg->conn);
|
netconn_drain(msg->conn);
|
||||||
LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
|
LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
|
||||||
msg->conn->write_offset == 0);
|
msg->conn->write_offset == 0);
|
||||||
@ -1266,12 +1328,13 @@ do_close(struct api_msg_msg *msg)
|
|||||||
msg->conn->current_msg = msg;
|
msg->conn->current_msg = msg;
|
||||||
do_close_internal(msg->conn);
|
do_close_internal(msg->conn);
|
||||||
/* for tcp netconns, do_close_internal ACKs the message */
|
/* for tcp netconns, do_close_internal ACKs the message */
|
||||||
|
return;
|
||||||
} else
|
} else
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
{
|
{
|
||||||
msg->err = ERR_VAL;
|
msg->err = ERR_VAL;
|
||||||
sys_sem_signal(msg->conn->op_completed);
|
|
||||||
}
|
}
|
||||||
|
sys_sem_signal(msg->conn->op_completed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LWIP_IGMP
|
#if LWIP_IGMP
|
||||||
|
@ -44,18 +44,18 @@ static const char *err_strerr[] = {
|
|||||||
"Ok.", /* ERR_OK 0 */
|
"Ok.", /* ERR_OK 0 */
|
||||||
"Out of memory error.", /* ERR_MEM -1 */
|
"Out of memory error.", /* ERR_MEM -1 */
|
||||||
"Buffer error.", /* ERR_BUF -2 */
|
"Buffer error.", /* ERR_BUF -2 */
|
||||||
"Timeout.", /* ERR_TIMEOUT -3 */
|
"Timeout.", /* ERR_TIMEOUT -3 */
|
||||||
"Routing problem.", /* ERR_RTE -4 */
|
"Routing problem.", /* ERR_RTE -4 */
|
||||||
"Connection aborted.", /* ERR_ABRT -5 */
|
"Operation in progress.", /* ERR_INPROGRESS -5 */
|
||||||
"Connection reset.", /* ERR_RST -6 */
|
"Illegal value.", /* ERR_VAL -6 */
|
||||||
"Connection closed.", /* ERR_CLSD -7 */
|
"Connection aborted.", /* ERR_ABRT -7 */
|
||||||
"Not connected.", /* ERR_CONN -8 */
|
"Connection reset.", /* ERR_RST -8 */
|
||||||
"Illegal value.", /* ERR_VAL -9 */
|
"Connection closed.", /* ERR_CLSD -9 */
|
||||||
"Illegal argument.", /* ERR_ARG -10 */
|
"Not connected.", /* ERR_CONN -10 */
|
||||||
"Address in use.", /* ERR_USE -11 */
|
"Illegal argument.", /* ERR_ARG -11 */
|
||||||
"Low-level netif error.", /* ERR_IF -12 */
|
"Address in use.", /* ERR_USE -12 */
|
||||||
"Already connected.", /* ERR_ISCONN -13 */
|
"Low-level netif error.", /* ERR_IF -13 */
|
||||||
"Operation in progress." /* ERR_INPROGRESS -14 */
|
"Already connected.", /* ERR_ISCONN -14 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,11 +67,9 @@ struct lwip_socket {
|
|||||||
/** number of times data was received, set by event_callback(),
|
/** number of times data was received, set by event_callback(),
|
||||||
tested by the receive and select functions */
|
tested by the receive and select functions */
|
||||||
s16_t rcvevent;
|
s16_t rcvevent;
|
||||||
/** number of times data was received, set by event_callback(),
|
/** number of times data was ACKed (free send buffer), set by event_callback(),
|
||||||
tested by select */
|
tested by select */
|
||||||
u16_t sendevent;
|
u16_t sendevent;
|
||||||
/** socket flags (currently, only used for O_NONBLOCK) */
|
|
||||||
u16_t flags;
|
|
||||||
/** last error that occurred on this socket */
|
/** last error that occurred on this socket */
|
||||||
int err;
|
int err;
|
||||||
};
|
};
|
||||||
@ -130,16 +128,16 @@ static const int err_to_errno_table[] = {
|
|||||||
ENOBUFS, /* ERR_BUF -2 Buffer error. */
|
ENOBUFS, /* ERR_BUF -2 Buffer error. */
|
||||||
ETIMEDOUT, /* ERR_TIMEOUT -3 Timeout */
|
ETIMEDOUT, /* ERR_TIMEOUT -3 Timeout */
|
||||||
EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */
|
EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */
|
||||||
ECONNABORTED, /* ERR_ABRT -5 Connection aborted. */
|
EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */
|
||||||
ECONNRESET, /* ERR_RST -6 Connection reset. */
|
EINVAL, /* ERR_VAL -6 Illegal value. */
|
||||||
ESHUTDOWN, /* ERR_CLSD -7 Connection closed. */
|
ECONNABORTED, /* ERR_ABRT -7 Connection aborted. */
|
||||||
ENOTCONN, /* ERR_CONN -8 Not connected. */
|
ECONNRESET, /* ERR_RST -8 Connection reset. */
|
||||||
EINVAL, /* ERR_VAL -9 Illegal value. */
|
ESHUTDOWN, /* ERR_CLSD -9 Connection closed. */
|
||||||
EIO, /* ERR_ARG -10 Illegal argument. */
|
ENOTCONN, /* ERR_CONN -10 Not connected. */
|
||||||
EADDRINUSE, /* ERR_USE -11 Address in use. */
|
EIO, /* ERR_ARG -11 Illegal argument. */
|
||||||
-1, /* ERR_IF -12 Low-level netif error */
|
EADDRINUSE, /* ERR_USE -12 Address in use. */
|
||||||
-1, /* ERR_ISCONN -13 Already connected. */
|
-1, /* ERR_IF -13 Low-level netif error */
|
||||||
EINPROGRESS /* ERR_INPROGRESS -14 Operation in progress */
|
-1, /* ERR_ISCONN -14 Already connected. */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ERR_TO_ERRNO_TABLE_SIZE \
|
#define ERR_TO_ERRNO_TABLE_SIZE \
|
||||||
@ -227,8 +225,8 @@ alloc_socket(struct netconn *newconn)
|
|||||||
sockets[i].lastdata = NULL;
|
sockets[i].lastdata = NULL;
|
||||||
sockets[i].lastoffset = 0;
|
sockets[i].lastoffset = 0;
|
||||||
sockets[i].rcvevent = 0;
|
sockets[i].rcvevent = 0;
|
||||||
sockets[i].sendevent = 1; /* TCP send buf is empty */
|
/* TCP sendbuf is empty, but not connected yet, so not yet writable */
|
||||||
sockets[i].flags = 0;
|
sockets[i].sendevent = (newconn->type == NETCONN_TCP ? 0 : 1);
|
||||||
sockets[i].err = 0;
|
sockets[i].err = 0;
|
||||||
sys_sem_signal(socksem);
|
sys_sem_signal(socksem);
|
||||||
return i;
|
return i;
|
||||||
@ -260,7 +258,7 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
|||||||
if (!sock)
|
if (!sock)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((sock->flags & O_NONBLOCK) && (sock->rcvevent <= 0)) {
|
if ((sock->conn->non_blocking) && (sock->rcvevent <= 0)) {
|
||||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s));
|
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s));
|
||||||
sock_set_errno(sock, EWOULDBLOCK);
|
sock_set_errno(sock, EWOULDBLOCK);
|
||||||
return -1;
|
return -1;
|
||||||
@ -494,7 +492,7 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
|
|||||||
buf = sock->lastdata;
|
buf = sock->lastdata;
|
||||||
} else {
|
} else {
|
||||||
/* If this is non-blocking call, then check first */
|
/* If this is non-blocking call, then check first */
|
||||||
if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK)) &&
|
if (((flags & MSG_DONTWAIT) || (sock->conn->non_blocking)) &&
|
||||||
(sock->rcvevent <= 0)) {
|
(sock->rcvevent <= 0)) {
|
||||||
if (off > 0) {
|
if (off > 0) {
|
||||||
/* already received data, return that */
|
/* already received data, return that */
|
||||||
@ -1958,10 +1956,10 @@ lwip_ioctl(int s, long cmd, void *argp)
|
|||||||
|
|
||||||
case FIONBIO:
|
case FIONBIO:
|
||||||
if (argp && *(u32_t*)argp)
|
if (argp && *(u32_t*)argp)
|
||||||
sock->flags |= O_NONBLOCK;
|
sock->conn->non_blocking = 1;
|
||||||
else
|
else
|
||||||
sock->flags &= ~O_NONBLOCK;
|
sock->conn->non_blocking = 0;
|
||||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, !!(sock->flags & O_NONBLOCK)));
|
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, sock->conn->non_blocking));
|
||||||
sock_set_errno(sock, 0);
|
sock_set_errno(sock, 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ extern "C" {
|
|||||||
#define NETCONNTYPE_GROUP(t) (t&0xF0)
|
#define NETCONNTYPE_GROUP(t) (t&0xF0)
|
||||||
#define NETCONNTYPE_DATAGRAM(t) (t&0xE0)
|
#define NETCONNTYPE_DATAGRAM(t) (t&0xE0)
|
||||||
|
|
||||||
|
/** Protocol family and type of the netconn */
|
||||||
enum netconn_type {
|
enum netconn_type {
|
||||||
NETCONN_INVALID = 0,
|
NETCONN_INVALID = 0,
|
||||||
/* NETCONN_TCP Group */
|
/* NETCONN_TCP Group */
|
||||||
@ -73,6 +74,8 @@ enum netconn_type {
|
|||||||
NETCONN_RAW = 0x40
|
NETCONN_RAW = 0x40
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Current state of the netconn. Non-TCP netconns are always
|
||||||
|
* in state NETCONN_NONE! */
|
||||||
enum netconn_state {
|
enum netconn_state {
|
||||||
NETCONN_NONE,
|
NETCONN_NONE,
|
||||||
NETCONN_WRITE,
|
NETCONN_WRITE,
|
||||||
@ -81,6 +84,7 @@ enum netconn_state {
|
|||||||
NETCONN_CLOSE
|
NETCONN_CLOSE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Use to inform the callback function about changes */
|
||||||
enum netconn_evt {
|
enum netconn_evt {
|
||||||
NETCONN_EVT_RCVPLUS,
|
NETCONN_EVT_RCVPLUS,
|
||||||
NETCONN_EVT_RCVMINUS,
|
NETCONN_EVT_RCVMINUS,
|
||||||
@ -89,6 +93,7 @@ enum netconn_evt {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if LWIP_IGMP
|
#if LWIP_IGMP
|
||||||
|
/** Used for netconn_join_leave_group() */
|
||||||
enum netconn_igmp {
|
enum netconn_igmp {
|
||||||
NETCONN_JOIN,
|
NETCONN_JOIN,
|
||||||
NETCONN_LEAVE
|
NETCONN_LEAVE
|
||||||
@ -152,10 +157,14 @@ struct netconn {
|
|||||||
#if LWIP_TCPIP_CORE_LOCKING
|
#if LWIP_TCPIP_CORE_LOCKING
|
||||||
/** TCP: when data passed to netconn_write doesn't fit into the send buffer,
|
/** TCP: when data passed to netconn_write doesn't fit into the send buffer,
|
||||||
this temporarily stores whether to wake up the original application task
|
this temporarily stores whether to wake up the original application task
|
||||||
if data couldn't be sent in the first try. */
|
if data couldn't be sent in the first try. @todo: combine in 'flags' */
|
||||||
u8_t write_delayed;
|
u8_t write_delayed;
|
||||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
|
/** Should this netconn avoid blocking? @todo: combine in 'flags' */
|
||||||
|
u8_t non_blocking;
|
||||||
|
/** Was the last connect action a non-blocking one? @todo: combine in 'flags' */
|
||||||
|
u8_t in_non_blocking_connect;
|
||||||
/** A callback function that is informed about events for this netconn */
|
/** A callback function that is informed about events for this netconn */
|
||||||
netconn_callback callback;
|
netconn_callback callback;
|
||||||
};
|
};
|
||||||
|
@ -54,24 +54,22 @@ typedef LWIP_ERR_T err_t;
|
|||||||
#define ERR_BUF -2 /* Buffer error. */
|
#define ERR_BUF -2 /* Buffer error. */
|
||||||
#define ERR_TIMEOUT -3 /* Timeout. */
|
#define ERR_TIMEOUT -3 /* Timeout. */
|
||||||
#define ERR_RTE -4 /* Routing problem. */
|
#define ERR_RTE -4 /* Routing problem. */
|
||||||
|
#define ERR_INPROGRESS -5 /* Operation in progress */
|
||||||
|
#define ERR_VAL -6 /* Illegal value. */
|
||||||
|
|
||||||
#define ERR_IS_FATAL(e) ((e) < ERR_RTE)
|
#define ERR_IS_FATAL(e) ((e) < ERR_VAL)
|
||||||
|
|
||||||
#define ERR_ABRT -5 /* Connection aborted. */
|
#define ERR_ABRT -7 /* Connection aborted. */
|
||||||
#define ERR_RST -6 /* Connection reset. */
|
#define ERR_RST -8 /* Connection reset. */
|
||||||
#define ERR_CLSD -7 /* Connection closed. */
|
#define ERR_CLSD -9 /* Connection closed. */
|
||||||
#define ERR_CONN -8 /* Not connected. */
|
#define ERR_CONN -10 /* Not connected. */
|
||||||
|
|
||||||
#define ERR_VAL -9 /* Illegal value. */
|
#define ERR_ARG -11 /* Illegal argument. */
|
||||||
|
|
||||||
#define ERR_ARG -10 /* Illegal argument. */
|
#define ERR_USE -12 /* Address in use. */
|
||||||
|
|
||||||
#define ERR_USE -11 /* Address in use. */
|
#define ERR_IF -13 /* Low-level netif error */
|
||||||
|
#define ERR_ISCONN -14 /* Already connected. */
|
||||||
#define ERR_IF -12 /* Low-level netif error */
|
|
||||||
#define ERR_ISCONN -13 /* Already connected. */
|
|
||||||
|
|
||||||
#define ERR_INPROGRESS -14 /* Operation in progress */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef LWIP_DEBUG
|
#ifdef LWIP_DEBUG
|
||||||
|
@ -262,10 +262,6 @@ typedef struct ip_mreq {
|
|||||||
#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */
|
#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Socket flags: */
|
|
||||||
#ifndef O_NONBLOCK
|
|
||||||
#define O_NONBLOCK 04000U
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* FD_SET used for lwip_select */
|
/* FD_SET used for lwip_select */
|
||||||
#ifndef FD_SET
|
#ifndef FD_SET
|
||||||
|
Loading…
Reference in New Issue
Block a user