mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-17 17:10:03 +00:00
task #10102: "netconn: clean up conn->err threading issues" by adding error return value to struct api_msg_msg
This commit is contained in:
parent
3e1cca65bd
commit
34139606ca
@ -52,7 +52,8 @@ HISTORY
|
|||||||
|
|
||||||
2010-01-17: Simon Goldschmidt
|
2010-01-17: Simon Goldschmidt
|
||||||
* api_lib.c, api_msg.c, (api_msg.h, api.h, sockets.c, tcpip.c):
|
* api_lib.c, api_msg.c, (api_msg.h, api.h, sockets.c, tcpip.c):
|
||||||
task #10102: Netconn: clean up conn->err threading issues
|
task #10102: "netconn: clean up conn->err threading issues" by adding
|
||||||
|
error return value to struct api_msg_msg
|
||||||
|
|
||||||
2010-01-17: Simon Goldschmidt
|
2010-01-17: Simon Goldschmidt
|
||||||
* api.h, api_lib.c, sockets.c: Changed netconn_recv() and netconn_accept()
|
* api.h, api_lib.c, sockets.c: Changed netconn_recv() and netconn_accept()
|
||||||
|
@ -71,13 +71,11 @@ netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_cal
|
|||||||
struct api_msg msg;
|
struct api_msg msg;
|
||||||
|
|
||||||
conn = netconn_alloc(t, callback);
|
conn = netconn_alloc(t, callback);
|
||||||
if (conn != NULL ) {
|
if (conn != NULL) {
|
||||||
msg.function = do_newconn;
|
msg.function = do_newconn;
|
||||||
msg.msg.msg.n.proto = proto;
|
msg.msg.msg.n.proto = proto;
|
||||||
msg.msg.conn = conn;
|
msg.msg.conn = conn;
|
||||||
TCPIP_APIMSG(&msg);
|
if (TCPIP_APIMSG(&msg) != ERR_OK) {
|
||||||
|
|
||||||
if (conn->err != ERR_OK) {
|
|
||||||
LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL);
|
LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL);
|
||||||
LWIP_ASSERT("conn has no op_completed", conn->op_completed != SYS_SEM_NULL);
|
LWIP_ASSERT("conn has no op_completed", conn->op_completed != SYS_SEM_NULL);
|
||||||
LWIP_ASSERT("conn has no recvmbox", conn->recvmbox != SYS_MBOX_NULL);
|
LWIP_ASSERT("conn has no recvmbox", conn->recvmbox != SYS_MBOX_NULL);
|
||||||
@ -116,6 +114,8 @@ netconn_delete(struct netconn *conn)
|
|||||||
conn->pcb.tcp = NULL;
|
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 */
|
||||||
|
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,6 +134,7 @@ err_t
|
|||||||
netconn_getaddr(struct netconn *conn, struct ip_addr *addr, u16_t *port, u8_t local)
|
netconn_getaddr(struct netconn *conn, struct ip_addr *addr, u16_t *port, u8_t local)
|
||||||
{
|
{
|
||||||
struct api_msg msg;
|
struct api_msg msg;
|
||||||
|
err_t err;
|
||||||
|
|
||||||
LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||||
LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;);
|
||||||
@ -144,9 +145,10 @@ netconn_getaddr(struct netconn *conn, struct ip_addr *addr, u16_t *port, u8_t lo
|
|||||||
msg.msg.msg.ad.ipaddr = addr;
|
msg.msg.msg.ad.ipaddr = addr;
|
||||||
msg.msg.msg.ad.port = port;
|
msg.msg.msg.ad.port = port;
|
||||||
msg.msg.msg.ad.local = local;
|
msg.msg.msg.ad.local = local;
|
||||||
TCPIP_APIMSG(&msg);
|
err = TCPIP_APIMSG(&msg);
|
||||||
|
|
||||||
return conn->err;
|
NETCONN_SET_SAFE_ERR(conn, err);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,6 +165,7 @@ err_t
|
|||||||
netconn_bind(struct netconn *conn, struct ip_addr *addr, u16_t port)
|
netconn_bind(struct netconn *conn, struct ip_addr *addr, u16_t port)
|
||||||
{
|
{
|
||||||
struct api_msg msg;
|
struct api_msg msg;
|
||||||
|
err_t err;
|
||||||
|
|
||||||
LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||||
|
|
||||||
@ -170,8 +173,10 @@ netconn_bind(struct netconn *conn, struct ip_addr *addr, u16_t port)
|
|||||||
msg.msg.conn = conn;
|
msg.msg.conn = conn;
|
||||||
msg.msg.msg.bc.ipaddr = addr;
|
msg.msg.msg.bc.ipaddr = addr;
|
||||||
msg.msg.msg.bc.port = port;
|
msg.msg.msg.bc.port = port;
|
||||||
TCPIP_APIMSG(&msg);
|
err = TCPIP_APIMSG(&msg);
|
||||||
return conn->err;
|
|
||||||
|
NETCONN_SET_SAFE_ERR(conn, err);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -186,6 +191,7 @@ err_t
|
|||||||
netconn_connect(struct netconn *conn, struct ip_addr *addr, u16_t port)
|
netconn_connect(struct netconn *conn, struct ip_addr *addr, u16_t port)
|
||||||
{
|
{
|
||||||
struct api_msg msg;
|
struct api_msg msg;
|
||||||
|
err_t err;
|
||||||
|
|
||||||
LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||||
|
|
||||||
@ -194,8 +200,10 @@ netconn_connect(struct netconn *conn, struct ip_addr *addr, u16_t port)
|
|||||||
msg.msg.msg.bc.ipaddr = addr;
|
msg.msg.msg.bc.ipaddr = addr;
|
||||||
msg.msg.msg.bc.port = port;
|
msg.msg.msg.bc.port = port;
|
||||||
/* This is the only function which need to not block tcpip_thread */
|
/* This is the only function which need to not block tcpip_thread */
|
||||||
tcpip_apimsg(&msg);
|
err = tcpip_apimsg(&msg);
|
||||||
return conn->err;
|
|
||||||
|
NETCONN_SET_SAFE_ERR(conn, err);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,13 +216,16 @@ err_t
|
|||||||
netconn_disconnect(struct netconn *conn)
|
netconn_disconnect(struct netconn *conn)
|
||||||
{
|
{
|
||||||
struct api_msg msg;
|
struct api_msg msg;
|
||||||
|
err_t err;
|
||||||
|
|
||||||
LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||||
|
|
||||||
msg.function = do_disconnect;
|
msg.function = do_disconnect;
|
||||||
msg.msg.conn = conn;
|
msg.msg.conn = conn;
|
||||||
TCPIP_APIMSG(&msg);
|
err = TCPIP_APIMSG(&msg);
|
||||||
return conn->err;
|
|
||||||
|
NETCONN_SET_SAFE_ERR(conn, err);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -229,6 +240,7 @@ err_t
|
|||||||
netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
|
netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
|
||||||
{
|
{
|
||||||
struct api_msg msg;
|
struct api_msg msg;
|
||||||
|
err_t err;
|
||||||
|
|
||||||
/* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */
|
/* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */
|
||||||
LWIP_UNUSED_ARG(backlog);
|
LWIP_UNUSED_ARG(backlog);
|
||||||
@ -240,8 +252,10 @@ netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
|
|||||||
#if TCP_LISTEN_BACKLOG
|
#if TCP_LISTEN_BACKLOG
|
||||||
msg.msg.msg.lb.backlog = backlog;
|
msg.msg.msg.lb.backlog = backlog;
|
||||||
#endif /* TCP_LISTEN_BACKLOG */
|
#endif /* TCP_LISTEN_BACKLOG */
|
||||||
TCPIP_APIMSG(&msg);
|
err = TCPIP_APIMSG(&msg);
|
||||||
return conn->err;
|
|
||||||
|
NETCONN_SET_SAFE_ERR(conn, err);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -256,17 +270,26 @@ err_t
|
|||||||
netconn_accept(struct netconn *conn, struct netconn **new_conn)
|
netconn_accept(struct netconn *conn, struct netconn **new_conn)
|
||||||
{
|
{
|
||||||
struct netconn *newconn;
|
struct netconn *newconn;
|
||||||
|
err_t err;
|
||||||
#if TCP_LISTEN_BACKLOG
|
#if TCP_LISTEN_BACKLOG
|
||||||
struct api_msg msg;
|
struct api_msg msg;
|
||||||
#endif /* TCP_LISTEN_BACKLOG */
|
#endif /* TCP_LISTEN_BACKLOG */
|
||||||
|
|
||||||
|
LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;);
|
||||||
|
*new_conn = NULL;
|
||||||
LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||||
LWIP_ERROR("netconn_accept: invalid acceptmbox", (conn->acceptmbox != SYS_MBOX_NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_accept: invalid acceptmbox", (conn->acceptmbox != SYS_MBOX_NULL), return ERR_ARG;);
|
||||||
LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;);
|
|
||||||
|
|
||||||
*new_conn = NULL;
|
err = conn->last_err;
|
||||||
|
if (ERR_IS_FATAL(err)) {
|
||||||
|
/* don't recv on fatal errors: this might block the application task
|
||||||
|
waiting on acceptmbox forever! */
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
#if LWIP_SO_RCVTIMEO
|
#if LWIP_SO_RCVTIMEO
|
||||||
if (sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
|
if (sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
|
||||||
|
NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
|
||||||
return ERR_TIMEOUT;
|
return ERR_TIMEOUT;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -277,16 +300,19 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
|
|||||||
|
|
||||||
if (newconn == NULL) {
|
if (newconn == NULL) {
|
||||||
/* connection has been closed */
|
/* connection has been closed */
|
||||||
|
NETCONN_SET_SAFE_ERR(conn, ERR_CLSD);
|
||||||
return ERR_CLSD;
|
return ERR_CLSD;
|
||||||
}
|
}
|
||||||
#if TCP_LISTEN_BACKLOG
|
#if TCP_LISTEN_BACKLOG
|
||||||
/* Let the stack know that we have accepted the connection. */
|
/* Let the stack know that we have accepted the connection. */
|
||||||
msg.function = do_recv;
|
msg.function = do_recv;
|
||||||
msg.msg.conn = conn;
|
msg.msg.conn = conn;
|
||||||
|
/* don't care for the return value of do_recv */
|
||||||
TCPIP_APIMSG(&msg);
|
TCPIP_APIMSG(&msg);
|
||||||
#endif /* TCP_LISTEN_BACKLOG */
|
#endif /* TCP_LISTEN_BACKLOG */
|
||||||
|
|
||||||
*new_conn = newconn;
|
*new_conn = newconn;
|
||||||
|
/* don't set conn->last_err: it's only ERR_OK, anyway */
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,18 +331,18 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
|
|||||||
struct netbuf *buf = NULL;
|
struct netbuf *buf = NULL;
|
||||||
struct pbuf *p;
|
struct pbuf *p;
|
||||||
u16_t len;
|
u16_t len;
|
||||||
|
err_t err;
|
||||||
|
|
||||||
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
|
|
||||||
LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
|
||||||
|
|
||||||
*new_buf = NULL;
|
*new_buf = NULL;
|
||||||
if (conn->recvmbox == SYS_MBOX_NULL) {
|
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||||
/* TCP listen conns don't have a recvmbox! */
|
LWIP_ERROR("netconn_accept: invalid recvmbox", (conn->recvmbox != SYS_MBOX_NULL), return ERR_CONN;);
|
||||||
return ERR_CONN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ERR_IS_FATAL(conn->err)) {
|
err = conn->last_err;
|
||||||
return conn->err;
|
if (ERR_IS_FATAL(err)) {
|
||||||
|
/* don't recv on fatal errors: this might block the application task
|
||||||
|
waiting on recvmbox forever! */
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->type == NETCONN_TCP) {
|
if (conn->type == NETCONN_TCP) {
|
||||||
@ -325,14 +351,14 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
|
|||||||
|
|
||||||
buf = memp_malloc(MEMP_NETBUF);
|
buf = memp_malloc(MEMP_NETBUF);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
conn->err = ERR_MEM;
|
NETCONN_SET_SAFE_ERR(conn, ERR_MEM);
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LWIP_SO_RCVTIMEO
|
#if LWIP_SO_RCVTIMEO
|
||||||
if (sys_arch_mbox_fetch(conn->recvmbox, (void *)&p, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
|
if (sys_arch_mbox_fetch(conn->recvmbox, (void *)&p, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
|
||||||
memp_free(MEMP_NETBUF, buf);
|
memp_free(MEMP_NETBUF, buf);
|
||||||
conn->err = ERR_TIMEOUT;
|
NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
|
||||||
return ERR_TIMEOUT;
|
return ERR_TIMEOUT;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -354,9 +380,7 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
|
|||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
memp_free(MEMP_NETBUF, buf);
|
memp_free(MEMP_NETBUF, buf);
|
||||||
/* Avoid to lose any previous error code */
|
/* Avoid to lose any previous error code */
|
||||||
if (conn->err == ERR_OK) {
|
NETCONN_SET_SAFE_ERR(conn, ERR_CLSD);
|
||||||
conn->err = ERR_CLSD;
|
|
||||||
}
|
|
||||||
return ERR_CLSD;
|
return ERR_CLSD;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,13 +399,14 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
|
|||||||
} else {
|
} else {
|
||||||
msg.msg.msg.r.len = 1;
|
msg.msg.msg.r.len = 1;
|
||||||
}
|
}
|
||||||
|
/* don't care for the return value of do_recv */
|
||||||
TCPIP_APIMSG(&msg);
|
TCPIP_APIMSG(&msg);
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
} else {
|
} else {
|
||||||
#if (LWIP_UDP || LWIP_RAW)
|
#if (LWIP_UDP || LWIP_RAW)
|
||||||
#if LWIP_SO_RCVTIMEO
|
#if LWIP_SO_RCVTIMEO
|
||||||
if (sys_arch_mbox_fetch(conn->recvmbox, (void *)&buf, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
|
if (sys_arch_mbox_fetch(conn->recvmbox, (void *)&buf, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
|
||||||
conn->err = ERR_TIMEOUT;
|
NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
|
||||||
return ERR_TIMEOUT;
|
return ERR_TIMEOUT;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -399,6 +424,7 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
|
|||||||
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p\n", (void *)buf));
|
LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p\n", (void *)buf));
|
||||||
|
|
||||||
*new_buf = buf;
|
*new_buf = buf;
|
||||||
|
/* don't set conn->last_err: it's only ERR_OK, anyway */
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,6 +460,7 @@ err_t
|
|||||||
netconn_send(struct netconn *conn, struct netbuf *buf)
|
netconn_send(struct netconn *conn, struct netbuf *buf)
|
||||||
{
|
{
|
||||||
struct api_msg msg;
|
struct api_msg msg;
|
||||||
|
err_t err;
|
||||||
|
|
||||||
LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||||
|
|
||||||
@ -441,8 +468,10 @@ netconn_send(struct netconn *conn, struct netbuf *buf)
|
|||||||
msg.function = do_send;
|
msg.function = do_send;
|
||||||
msg.msg.conn = conn;
|
msg.msg.conn = conn;
|
||||||
msg.msg.msg.b = buf;
|
msg.msg.msg.b = buf;
|
||||||
TCPIP_APIMSG(&msg);
|
err = TCPIP_APIMSG(&msg);
|
||||||
return conn->err;
|
|
||||||
|
NETCONN_SET_SAFE_ERR(conn, err);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -460,6 +489,7 @@ err_t
|
|||||||
netconn_write(struct netconn *conn, const void *dataptr, size_t size, u8_t apiflags)
|
netconn_write(struct netconn *conn, const void *dataptr, size_t size, u8_t apiflags)
|
||||||
{
|
{
|
||||||
struct api_msg msg;
|
struct api_msg msg;
|
||||||
|
err_t err;
|
||||||
|
|
||||||
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;);
|
||||||
@ -472,8 +502,10 @@ netconn_write(struct netconn *conn, const void *dataptr, size_t size, u8_t apifl
|
|||||||
/* For locking the core: this _can_ be delayed on low memory/low send buffer,
|
/* For locking the core: this _can_ be delayed on low memory/low send buffer,
|
||||||
but if it is, this is done inside api_msg.c:do_write(), so we can use the
|
but if it is, this is done inside api_msg.c:do_write(), so we can use the
|
||||||
non-blocking version here. */
|
non-blocking version here. */
|
||||||
TCPIP_APIMSG(&msg);
|
err = TCPIP_APIMSG(&msg);
|
||||||
return conn->err;
|
|
||||||
|
NETCONN_SET_SAFE_ERR(conn, err);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -486,13 +518,18 @@ err_t
|
|||||||
netconn_close(struct netconn *conn)
|
netconn_close(struct netconn *conn)
|
||||||
{
|
{
|
||||||
struct api_msg msg;
|
struct api_msg msg;
|
||||||
|
err_t err;
|
||||||
|
|
||||||
LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||||
|
|
||||||
msg.function = do_close;
|
msg.function = do_close;
|
||||||
msg.msg.conn = conn;
|
msg.msg.conn = conn;
|
||||||
tcpip_apimsg(&msg);
|
/* because of the LWIP_TCPIP_CORE_LOCKING implementation of do_close,
|
||||||
return conn->err;
|
don't use TCPIP_APIMSG here */
|
||||||
|
err = tcpip_apimsg(&msg);
|
||||||
|
|
||||||
|
NETCONN_SET_SAFE_ERR(conn, err);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LWIP_IGMP
|
#if LWIP_IGMP
|
||||||
@ -513,6 +550,7 @@ netconn_join_leave_group(struct netconn *conn,
|
|||||||
enum netconn_igmp join_or_leave)
|
enum netconn_igmp join_or_leave)
|
||||||
{
|
{
|
||||||
struct api_msg msg;
|
struct api_msg msg;
|
||||||
|
err_t err;
|
||||||
|
|
||||||
LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
|
LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||||
|
|
||||||
@ -521,8 +559,10 @@ netconn_join_leave_group(struct netconn *conn,
|
|||||||
msg.msg.msg.jl.multiaddr = multiaddr;
|
msg.msg.msg.jl.multiaddr = multiaddr;
|
||||||
msg.msg.msg.jl.interface = interface;
|
msg.msg.msg.jl.interface = interface;
|
||||||
msg.msg.msg.jl.join_or_leave = join_or_leave;
|
msg.msg.msg.jl.join_or_leave = join_or_leave;
|
||||||
TCPIP_APIMSG(&msg);
|
err = TCPIP_APIMSG(&msg);
|
||||||
return conn->err;
|
|
||||||
|
NETCONN_SET_SAFE_ERR(conn, err);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
#endif /* LWIP_IGMP */
|
#endif /* LWIP_IGMP */
|
||||||
|
|
||||||
|
@ -221,7 +221,9 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
|
|||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->err = err;
|
/* don't overwrite fatal errors! */
|
||||||
|
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);
|
SYS_ARCH_INC(conn->recv_avail, len);
|
||||||
@ -309,33 +311,43 @@ static void
|
|||||||
err_tcp(void *arg, err_t err)
|
err_tcp(void *arg, err_t err)
|
||||||
{
|
{
|
||||||
struct netconn *conn;
|
struct netconn *conn;
|
||||||
|
enum netconn_state old_state;
|
||||||
|
|
||||||
conn = arg;
|
conn = arg;
|
||||||
LWIP_ASSERT("conn != NULL", (conn != NULL));
|
LWIP_ASSERT("conn != NULL", (conn != NULL));
|
||||||
|
|
||||||
conn->pcb.tcp = NULL;
|
conn->pcb.tcp = NULL;
|
||||||
|
|
||||||
conn->err = err;
|
/* no protection since this is always fatal */
|
||||||
|
conn->last_err = err;
|
||||||
|
|
||||||
|
/* API_EVENT might call tcp_tmr, so reset conn->state now */
|
||||||
|
old_state = conn->state;
|
||||||
|
conn->state = NETCONN_NONE;
|
||||||
|
|
||||||
if (conn->recvmbox != SYS_MBOX_NULL) {
|
if (conn->recvmbox != SYS_MBOX_NULL) {
|
||||||
/* Register event with callback */
|
/* Register event with callback */
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
||||||
sys_mbox_post(conn->recvmbox, NULL);
|
sys_mbox_post(conn->recvmbox, NULL);
|
||||||
}
|
}
|
||||||
if (conn->op_completed != SYS_SEM_NULL && conn->state == NETCONN_CONNECT) {
|
|
||||||
conn->state = NETCONN_NONE;
|
|
||||||
sys_sem_signal(conn->op_completed);
|
|
||||||
}
|
|
||||||
if (conn->acceptmbox != SYS_MBOX_NULL) {
|
if (conn->acceptmbox != SYS_MBOX_NULL) {
|
||||||
/* Register event with callback */
|
/* Register event with callback */
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
||||||
sys_mbox_post(conn->acceptmbox, NULL);
|
sys_mbox_post(conn->acceptmbox, NULL);
|
||||||
}
|
}
|
||||||
if ((conn->state == NETCONN_WRITE) || (conn->state == NETCONN_CLOSE)) {
|
if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
|
||||||
|
(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! */
|
||||||
conn->state = NETCONN_NONE;
|
|
||||||
|
/* set error return code */
|
||||||
|
LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
|
||||||
|
conn->current_msg->err = err;
|
||||||
|
conn->current_msg = NULL;
|
||||||
/* wake up the waiting task */
|
/* wake up the waiting task */
|
||||||
sys_sem_signal(conn->op_completed);
|
sys_sem_signal(conn->op_completed);
|
||||||
|
} else {
|
||||||
|
LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,7 +402,9 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
|
|||||||
}
|
}
|
||||||
newconn->pcb.tcp = newpcb;
|
newconn->pcb.tcp = newpcb;
|
||||||
setup_tcp(newconn);
|
setup_tcp(newconn);
|
||||||
newconn->err = err;
|
/* no protection: when creating the pcb, the netconn is not yet known
|
||||||
|
to the application thread */
|
||||||
|
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 connection is aborted in tcp_process(),
|
||||||
@ -417,60 +431,56 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
|
|||||||
* @param msg the api_msg_msg describing the connection type
|
* @param msg the api_msg_msg describing the connection type
|
||||||
* @return msg->conn->err, but the return value is currently ignored
|
* @return msg->conn->err, but the return value is currently ignored
|
||||||
*/
|
*/
|
||||||
static err_t
|
static void
|
||||||
pcb_new(struct api_msg_msg *msg)
|
pcb_new(struct api_msg_msg *msg)
|
||||||
{
|
{
|
||||||
msg->conn->err = ERR_OK;
|
LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);
|
||||||
|
|
||||||
LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);
|
/* Allocate a PCB for this connection */
|
||||||
|
switch(NETCONNTYPE_GROUP(msg->conn->type)) {
|
||||||
/* Allocate a PCB for this connection */
|
|
||||||
switch(NETCONNTYPE_GROUP(msg->conn->type)) {
|
|
||||||
#if LWIP_RAW
|
#if LWIP_RAW
|
||||||
case NETCONN_RAW:
|
case NETCONN_RAW:
|
||||||
msg->conn->pcb.raw = raw_new(msg->msg.n.proto);
|
msg->conn->pcb.raw = raw_new(msg->msg.n.proto);
|
||||||
if(msg->conn->pcb.raw == NULL) {
|
if(msg->conn->pcb.raw == NULL) {
|
||||||
msg->conn->err = ERR_MEM;
|
msg->err = ERR_MEM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
|
raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_RAW */
|
#endif /* LWIP_RAW */
|
||||||
#if LWIP_UDP
|
#if LWIP_UDP
|
||||||
case NETCONN_UDP:
|
case NETCONN_UDP:
|
||||||
msg->conn->pcb.udp = udp_new();
|
msg->conn->pcb.udp = udp_new();
|
||||||
if(msg->conn->pcb.udp == NULL) {
|
if(msg->conn->pcb.udp == NULL) {
|
||||||
msg->conn->err = ERR_MEM;
|
msg->err = ERR_MEM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if LWIP_UDPLITE
|
#if LWIP_UDPLITE
|
||||||
if (msg->conn->type==NETCONN_UDPLITE) {
|
if (msg->conn->type==NETCONN_UDPLITE) {
|
||||||
udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
|
udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
|
||||||
}
|
}
|
||||||
#endif /* LWIP_UDPLITE */
|
#endif /* LWIP_UDPLITE */
|
||||||
if (msg->conn->type==NETCONN_UDPNOCHKSUM) {
|
if (msg->conn->type==NETCONN_UDPNOCHKSUM) {
|
||||||
udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
|
udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
|
||||||
}
|
}
|
||||||
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
|
udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_UDP */
|
#endif /* LWIP_UDP */
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
case NETCONN_TCP:
|
case NETCONN_TCP:
|
||||||
msg->conn->pcb.tcp = tcp_new();
|
msg->conn->pcb.tcp = tcp_new();
|
||||||
if(msg->conn->pcb.tcp == NULL) {
|
if(msg->conn->pcb.tcp == NULL) {
|
||||||
msg->conn->err = ERR_MEM;
|
msg->err = ERR_MEM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
setup_tcp(msg->conn);
|
setup_tcp(msg->conn);
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
default:
|
default:
|
||||||
/* Unsupported netconn type, e.g. protocol disabled */
|
/* Unsupported netconn type, e.g. protocol disabled */
|
||||||
msg->conn->err = ERR_VAL;
|
msg->err = ERR_VAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return msg->conn->err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -482,14 +492,15 @@ pcb_new(struct api_msg_msg *msg)
|
|||||||
void
|
void
|
||||||
do_newconn(struct api_msg_msg *msg)
|
do_newconn(struct api_msg_msg *msg)
|
||||||
{
|
{
|
||||||
if(msg->conn->pcb.tcp == NULL) {
|
msg->err = ERR_OK;
|
||||||
pcb_new(msg);
|
if(msg->conn->pcb.tcp == NULL) {
|
||||||
}
|
pcb_new(msg);
|
||||||
/* Else? This "new" connection already has a PCB allocated. */
|
}
|
||||||
/* Is this an error condition? Should it be deleted? */
|
/* Else? This "new" connection already has a PCB allocated. */
|
||||||
/* We currently just are happy and return. */
|
/* Is this an error condition? Should it be deleted? */
|
||||||
|
/* We currently just are happy and return. */
|
||||||
|
|
||||||
TCPIP_APIMSG_ACK(msg);
|
TCPIP_APIMSG_ACK(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -513,7 +524,7 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->err = ERR_OK;
|
conn->last_err = ERR_OK;
|
||||||
conn->type = t;
|
conn->type = t;
|
||||||
conn->pcb.tcp = NULL;
|
conn->pcb.tcp = NULL;
|
||||||
|
|
||||||
@ -560,7 +571,7 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
|
|||||||
conn->callback = callback;
|
conn->callback = callback;
|
||||||
conn->recv_avail = 0;
|
conn->recv_avail = 0;
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
conn->write_msg = NULL;
|
conn->current_msg = NULL;
|
||||||
conn->write_offset = 0;
|
conn->write_offset = 0;
|
||||||
#if LWIP_TCPIP_CORE_LOCKING
|
#if LWIP_TCPIP_CORE_LOCKING
|
||||||
conn->write_delayed = 0;
|
conn->write_delayed = 0;
|
||||||
@ -665,6 +676,7 @@ do_close_internal(struct netconn *conn)
|
|||||||
LWIP_ASSERT("this is for tcp netconns only", (conn->type == NETCONN_TCP));
|
LWIP_ASSERT("this is for tcp netconns only", (conn->type == NETCONN_TCP));
|
||||||
LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE));
|
LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE));
|
||||||
LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL));
|
LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL));
|
||||||
|
LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);
|
||||||
|
|
||||||
/* Set back some callback pointers */
|
/* Set back some callback pointers */
|
||||||
tcp_arg(conn->pcb.tcp, NULL);
|
tcp_arg(conn->pcb.tcp, NULL);
|
||||||
@ -682,10 +694,11 @@ do_close_internal(struct netconn *conn)
|
|||||||
err = tcp_close(conn->pcb.tcp);
|
err = tcp_close(conn->pcb.tcp);
|
||||||
if (err == ERR_OK) {
|
if (err == ERR_OK) {
|
||||||
/* Closing succeeded */
|
/* Closing succeeded */
|
||||||
|
conn->current_msg->err = ERR_OK;
|
||||||
|
conn->current_msg = NULL;
|
||||||
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;
|
||||||
conn->err = ERR_OK;
|
|
||||||
/* Trigger select() in socket layer. This send should something else so the
|
/* Trigger select() in socket layer. This send should something else so the
|
||||||
errorfd is set, not the read and write fd! */
|
errorfd is set, not the read and write fd! */
|
||||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
||||||
@ -734,8 +747,11 @@ do_delconn(struct api_msg_msg *msg)
|
|||||||
#endif /* LWIP_UDP */
|
#endif /* LWIP_UDP */
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
case NETCONN_TCP:
|
case NETCONN_TCP:
|
||||||
msg->conn->state = NETCONN_CLOSE;
|
LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
|
||||||
do_close_internal(msg->conn);
|
msg->conn->write_offset == 0);
|
||||||
|
msg->conn->state = NETCONN_CLOSE;
|
||||||
|
msg->conn->current_msg = msg;
|
||||||
|
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;
|
||||||
@ -766,30 +782,30 @@ do_delconn(struct api_msg_msg *msg)
|
|||||||
void
|
void
|
||||||
do_bind(struct api_msg_msg *msg)
|
do_bind(struct api_msg_msg *msg)
|
||||||
{
|
{
|
||||||
if (!ERR_IS_FATAL(msg->conn->err)) {
|
if (ERR_IS_FATAL(msg->conn->last_err)) {
|
||||||
|
msg->err = msg->conn->last_err;
|
||||||
|
} else {
|
||||||
|
msg->err = ERR_VAL;
|
||||||
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:
|
||||||
msg->conn->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
|
msg->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_RAW */
|
#endif /* LWIP_RAW */
|
||||||
#if LWIP_UDP
|
#if LWIP_UDP
|
||||||
case NETCONN_UDP:
|
case NETCONN_UDP:
|
||||||
msg->conn->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
|
msg->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_UDP */
|
#endif /* LWIP_UDP */
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
case NETCONN_TCP:
|
case NETCONN_TCP:
|
||||||
msg->conn->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port);
|
msg->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port);
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
/* msg->conn->pcb is NULL */
|
|
||||||
msg->conn->err = ERR_VAL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TCPIP_APIMSG_ACK(msg);
|
TCPIP_APIMSG_ACK(msg);
|
||||||
@ -815,10 +831,14 @@ do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
|
|||||||
return ERR_VAL;
|
return ERR_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->err = err;
|
LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT);
|
||||||
|
LWIP_ASSERT("conn->current_msg != NULL", 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);
|
||||||
}
|
}
|
||||||
|
conn->current_msg = NULL;
|
||||||
conn->state = NETCONN_NONE;
|
conn->state = NETCONN_NONE;
|
||||||
sys_sem_signal(conn->op_completed);
|
sys_sem_signal(conn->op_completed);
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
@ -837,7 +857,7 @@ 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->conn->err = ERR_CLSD;
|
msg->err = ERR_CLSD;
|
||||||
sys_sem_signal(msg->conn->op_completed);
|
sys_sem_signal(msg->conn->op_completed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -845,28 +865,29 @@ do_connect(struct api_msg_msg *msg)
|
|||||||
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->conn->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);
|
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->conn->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);
|
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:
|
||||||
msg->conn->state = NETCONN_CONNECT;
|
msg->conn->state = NETCONN_CONNECT;
|
||||||
|
msg->conn->current_msg = msg;
|
||||||
setup_tcp(msg->conn);
|
setup_tcp(msg->conn);
|
||||||
msg->conn->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port,
|
msg->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port,
|
||||||
do_connected);
|
do_connected);
|
||||||
/* sys_sem_signal() is called from do_connected (or err_tcp()),
|
/* sys_sem_signal() is called from do_connected (or err_tcp()),
|
||||||
* when the connection is established! */
|
* when the connection is established! */
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
default:
|
default:
|
||||||
LWIP_ERROR("Invalid netconn type", 0, do{ msg->conn->err = ERR_VAL;
|
LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL;
|
||||||
sys_sem_signal(msg->conn->op_completed); }while(0));
|
sys_sem_signal(msg->conn->op_completed); }while(0));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -885,8 +906,12 @@ do_disconnect(struct api_msg_msg *msg)
|
|||||||
#if LWIP_UDP
|
#if LWIP_UDP
|
||||||
if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
|
if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
|
||||||
udp_disconnect(msg->conn->pcb.udp);
|
udp_disconnect(msg->conn->pcb.udp);
|
||||||
}
|
msg->err = ERR_OK;
|
||||||
|
} else
|
||||||
#endif /* LWIP_UDP */
|
#endif /* LWIP_UDP */
|
||||||
|
{
|
||||||
|
msg->err = ERR_VAL;
|
||||||
|
}
|
||||||
TCPIP_APIMSG_ACK(msg);
|
TCPIP_APIMSG_ACK(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -900,7 +925,10 @@ void
|
|||||||
do_listen(struct api_msg_msg *msg)
|
do_listen(struct api_msg_msg *msg)
|
||||||
{
|
{
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
if (!ERR_IS_FATAL(msg->conn->err)) {
|
if (ERR_IS_FATAL(msg->conn->last_err)) {
|
||||||
|
msg->err = msg->conn->last_err;
|
||||||
|
} else {
|
||||||
|
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->pcb.tcp->state == CLOSED) {
|
||||||
@ -910,7 +938,7 @@ do_listen(struct api_msg_msg *msg)
|
|||||||
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) {
|
||||||
msg->conn->err = ERR_MEM;
|
msg->err = ERR_MEM;
|
||||||
} else {
|
} else {
|
||||||
/* delete the recvmbox and allocate the acceptmbox */
|
/* delete the recvmbox and allocate the acceptmbox */
|
||||||
if (msg->conn->recvmbox != SYS_MBOX_NULL) {
|
if (msg->conn->recvmbox != SYS_MBOX_NULL) {
|
||||||
@ -918,20 +946,19 @@ do_listen(struct api_msg_msg *msg)
|
|||||||
sys_mbox_free(msg->conn->recvmbox);
|
sys_mbox_free(msg->conn->recvmbox);
|
||||||
msg->conn->recvmbox = SYS_MBOX_NULL;
|
msg->conn->recvmbox = SYS_MBOX_NULL;
|
||||||
}
|
}
|
||||||
|
msg->err = ERR_OK;
|
||||||
if (msg->conn->acceptmbox == SYS_MBOX_NULL) {
|
if (msg->conn->acceptmbox == SYS_MBOX_NULL) {
|
||||||
if ((msg->conn->acceptmbox = sys_mbox_new(DEFAULT_ACCEPTMBOX_SIZE)) == SYS_MBOX_NULL) {
|
if ((msg->conn->acceptmbox = sys_mbox_new(DEFAULT_ACCEPTMBOX_SIZE)) == SYS_MBOX_NULL) {
|
||||||
msg->conn->err = ERR_MEM;
|
msg->err = ERR_MEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (msg->conn->err == ERR_OK) {
|
if (msg->err == ERR_OK) {
|
||||||
msg->conn->state = NETCONN_LISTEN;
|
msg->conn->state = NETCONN_LISTEN;
|
||||||
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 {
|
|
||||||
msg->conn->err = ERR_CONN;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -949,24 +976,27 @@ do_listen(struct api_msg_msg *msg)
|
|||||||
void
|
void
|
||||||
do_send(struct api_msg_msg *msg)
|
do_send(struct api_msg_msg *msg)
|
||||||
{
|
{
|
||||||
if (!ERR_IS_FATAL(msg->conn->err)) {
|
if (ERR_IS_FATAL(msg->conn->last_err)) {
|
||||||
|
msg->err = msg->conn->last_err;
|
||||||
|
} else {
|
||||||
|
msg->err = ERR_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:
|
||||||
if (msg->msg.b->addr == NULL) {
|
if (msg->msg.b->addr == NULL) {
|
||||||
msg->conn->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p);
|
msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p);
|
||||||
} else {
|
} else {
|
||||||
msg->conn->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, msg->msg.b->addr);
|
msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, msg->msg.b->addr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if LWIP_UDP
|
#if LWIP_UDP
|
||||||
case NETCONN_UDP:
|
case NETCONN_UDP:
|
||||||
if (msg->msg.b->addr == NULL) {
|
if (msg->msg.b->addr == NULL) {
|
||||||
msg->conn->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
|
msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
|
||||||
} else {
|
} else {
|
||||||
msg->conn->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->addr, msg->msg.b->port);
|
msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->addr, msg->msg.b->port);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_UDP */
|
#endif /* LWIP_UDP */
|
||||||
@ -988,17 +1018,16 @@ void
|
|||||||
do_recv(struct api_msg_msg *msg)
|
do_recv(struct api_msg_msg *msg)
|
||||||
{
|
{
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
if (!ERR_IS_FATAL(msg->conn->err)) {
|
msg->err = ERR_OK;
|
||||||
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 TCP_LISTEN_BACKLOG
|
#if TCP_LISTEN_BACKLOG
|
||||||
if (msg->conn->pcb.tcp->state == LISTEN) {
|
if (msg->conn->pcb.tcp->state == LISTEN) {
|
||||||
tcp_accepted(msg->conn->pcb.tcp);
|
tcp_accepted(msg->conn->pcb.tcp);
|
||||||
} else
|
} else
|
||||||
#endif /* TCP_LISTEN_BACKLOG */
|
#endif /* TCP_LISTEN_BACKLOG */
|
||||||
{
|
{
|
||||||
tcp_recved(msg->conn->pcb.tcp, msg->msg.r.len);
|
tcp_recved(msg->conn->pcb.tcp, msg->msg.r.len);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1027,10 +1056,12 @@ do_writemore(struct netconn *conn)
|
|||||||
u8_t write_finished = 0;
|
u8_t write_finished = 0;
|
||||||
size_t diff;
|
size_t diff;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
dataptr = (u8_t*)conn->write_msg->msg.w.dataptr + conn->write_offset;
|
dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset;
|
||||||
diff = conn->write_msg->msg.w.len - conn->write_offset;
|
diff = conn->current_msg->msg.w.len - conn->write_offset;
|
||||||
if (diff > 0xffffUL) { /* max_u16_t */
|
if (diff > 0xffffUL) { /* max_u16_t */
|
||||||
len = 0xffff;
|
len = 0xffff;
|
||||||
#if LWIP_TCPIP_CORE_LOCKING
|
#if LWIP_TCPIP_CORE_LOCKING
|
||||||
@ -1048,20 +1079,18 @@ do_writemore(struct netconn *conn)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tcp_write(conn->pcb.tcp, dataptr, len, conn->write_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->write_msg->msg.w.len));
|
LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len));
|
||||||
if (err == ERR_OK) {
|
if (err == ERR_OK) {
|
||||||
conn->write_offset += len;
|
conn->write_offset += len;
|
||||||
if (conn->write_offset == conn->write_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_msg = NULL;
|
|
||||||
conn->write_offset = 0;
|
conn->write_offset = 0;
|
||||||
/* API_EVENT might call tcp_tmr, so reset conn->state now */
|
/* API_EVENT might call tcp_tmr, so reset conn->state now */
|
||||||
conn->state = NETCONN_NONE;
|
conn->state = NETCONN_NONE;
|
||||||
}
|
}
|
||||||
err = tcp_output_nagle(conn->pcb.tcp);
|
err = tcp_output_nagle(conn->pcb.tcp);
|
||||||
conn->err = err;
|
|
||||||
if ((err == ERR_OK) && (tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT)) {
|
if ((err == ERR_OK) && (tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT)) {
|
||||||
API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
|
API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
|
||||||
}
|
}
|
||||||
@ -1079,13 +1108,14 @@ do_writemore(struct netconn *conn)
|
|||||||
} else {
|
} else {
|
||||||
/* On errors != ERR_MEM, we don't try writing any more but return
|
/* On errors != ERR_MEM, we don't try writing any more but return
|
||||||
the error to the application thread. */
|
the error to the application thread. */
|
||||||
conn->err = err;
|
|
||||||
write_finished = 1;
|
write_finished = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_finished) {
|
if (write_finished) {
|
||||||
/* everything was written: set back connection state
|
/* everything was written: set back connection state
|
||||||
and back to application task */
|
and back to application task */
|
||||||
|
conn->current_msg->err = err;
|
||||||
|
conn->current_msg = NULL;
|
||||||
conn->state = NETCONN_NONE;
|
conn->state = NETCONN_NONE;
|
||||||
#if LWIP_TCPIP_CORE_LOCKING
|
#if LWIP_TCPIP_CORE_LOCKING
|
||||||
if (conn->write_delayed != 0)
|
if (conn->write_delayed != 0)
|
||||||
@ -1111,33 +1141,42 @@ do_writemore(struct netconn *conn)
|
|||||||
void
|
void
|
||||||
do_write(struct api_msg_msg *msg)
|
do_write(struct api_msg_msg *msg)
|
||||||
{
|
{
|
||||||
if (!ERR_IS_FATAL(msg->conn->err)) {
|
if (ERR_IS_FATAL(msg->conn->last_err)) {
|
||||||
if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
|
msg->err = msg->conn->last_err;
|
||||||
|
} else {
|
||||||
|
if (msg->conn->type == NETCONN_TCP) {
|
||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
msg->conn->state = NETCONN_WRITE;
|
if (msg->conn->pcb.tcp != NULL) {
|
||||||
/* set all the variables used by do_writemore */
|
msg->conn->state = NETCONN_WRITE;
|
||||||
LWIP_ASSERT("already writing", msg->conn->write_msg == NULL &&
|
/* set all the variables used by do_writemore */
|
||||||
msg->conn->write_offset == 0);
|
LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
|
||||||
msg->conn->write_msg = msg;
|
msg->conn->write_offset == 0);
|
||||||
msg->conn->write_offset = 0;
|
msg->conn->current_msg = msg;
|
||||||
|
msg->conn->write_offset = 0;
|
||||||
#if LWIP_TCPIP_CORE_LOCKING
|
#if LWIP_TCPIP_CORE_LOCKING
|
||||||
msg->conn->write_delayed = 0;
|
msg->conn->write_delayed = 0;
|
||||||
if (do_writemore(msg->conn) != ERR_OK) {
|
if (do_writemore(msg->conn) != ERR_OK) {
|
||||||
LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE);
|
LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE);
|
||||||
UNLOCK_TCPIP_CORE();
|
UNLOCK_TCPIP_CORE();
|
||||||
sys_arch_sem_wait(msg->conn->op_completed, 0);
|
sys_arch_sem_wait(msg->conn->op_completed, 0);
|
||||||
LOCK_TCPIP_CORE();
|
LOCK_TCPIP_CORE();
|
||||||
LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
|
LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
|
||||||
|
}
|
||||||
|
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||||
|
do_writemore(msg->conn);
|
||||||
|
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||||
|
/* for both cases: if do_writemore was called, don't ACK the APIMSG
|
||||||
|
since do_writemore ACKs it! */
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
msg->err = ERR_CONN;
|
||||||
}
|
}
|
||||||
#else
|
#else /* LWIP_TCP */
|
||||||
do_writemore(msg->conn);
|
msg->err = ERR_VAL;
|
||||||
#endif
|
|
||||||
/* for both cases: if do_writemore was called, don't ACK the APIMSG! */
|
|
||||||
return;
|
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
#if (LWIP_UDP || LWIP_RAW)
|
#if (LWIP_UDP || LWIP_RAW)
|
||||||
} else {
|
} else {
|
||||||
msg->conn->err = ERR_VAL;
|
msg->err = ERR_VAL;
|
||||||
#endif /* (LWIP_UDP || LWIP_RAW) */
|
#endif /* (LWIP_UDP || LWIP_RAW) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1155,7 +1194,8 @@ do_getaddr(struct api_msg_msg *msg)
|
|||||||
{
|
{
|
||||||
if (msg->conn->pcb.ip != NULL) {
|
if (msg->conn->pcb.ip != NULL) {
|
||||||
*(msg->msg.ad.ipaddr) = (msg->msg.ad.local?msg->conn->pcb.ip->local_ip:msg->conn->pcb.ip->remote_ip);
|
*(msg->msg.ad.ipaddr) = (msg->msg.ad.local?msg->conn->pcb.ip->local_ip:msg->conn->pcb.ip->remote_ip);
|
||||||
|
|
||||||
|
msg->err = ERR_OK;
|
||||||
switch (NETCONNTYPE_GROUP(msg->conn->type)) {
|
switch (NETCONNTYPE_GROUP(msg->conn->type)) {
|
||||||
#if LWIP_RAW
|
#if LWIP_RAW
|
||||||
case NETCONN_RAW:
|
case NETCONN_RAW:
|
||||||
@ -1163,7 +1203,7 @@ do_getaddr(struct api_msg_msg *msg)
|
|||||||
*(msg->msg.ad.port) = msg->conn->pcb.raw->protocol;
|
*(msg->msg.ad.port) = msg->conn->pcb.raw->protocol;
|
||||||
} else {
|
} else {
|
||||||
/* return an error as connecting is only a helper for upper layers */
|
/* return an error as connecting is only a helper for upper layers */
|
||||||
msg->conn->err = ERR_CONN;
|
msg->err = ERR_CONN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* LWIP_RAW */
|
#endif /* LWIP_RAW */
|
||||||
@ -1173,7 +1213,7 @@ do_getaddr(struct api_msg_msg *msg)
|
|||||||
*(msg->msg.ad.port) = msg->conn->pcb.udp->local_port;
|
*(msg->msg.ad.port) = msg->conn->pcb.udp->local_port;
|
||||||
} else {
|
} else {
|
||||||
if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) {
|
if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) {
|
||||||
msg->conn->err = ERR_CONN;
|
msg->err = ERR_CONN;
|
||||||
} else {
|
} else {
|
||||||
*(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port;
|
*(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port;
|
||||||
}
|
}
|
||||||
@ -1187,7 +1227,7 @@ do_getaddr(struct api_msg_msg *msg)
|
|||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
msg->conn->err = ERR_CONN;
|
msg->err = ERR_CONN;
|
||||||
}
|
}
|
||||||
TCPIP_APIMSG_ACK(msg);
|
TCPIP_APIMSG_ACK(msg);
|
||||||
}
|
}
|
||||||
@ -1204,13 +1244,16 @@ do_close(struct api_msg_msg *msg)
|
|||||||
#if LWIP_TCP
|
#if LWIP_TCP
|
||||||
if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
|
if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
|
||||||
netconn_drain(msg->conn);
|
netconn_drain(msg->conn);
|
||||||
|
LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&
|
||||||
|
msg->conn->write_offset == 0);
|
||||||
msg->conn->state = NETCONN_CLOSE;
|
msg->conn->state = NETCONN_CLOSE;
|
||||||
|
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 */
|
||||||
} else
|
} else
|
||||||
#endif /* LWIP_TCP */
|
#endif /* LWIP_TCP */
|
||||||
{
|
{
|
||||||
msg->conn->err = ERR_VAL;
|
msg->err = ERR_VAL;
|
||||||
sys_sem_signal(msg->conn->op_completed);
|
sys_sem_signal(msg->conn->op_completed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1225,21 +1268,25 @@ do_close(struct api_msg_msg *msg)
|
|||||||
void
|
void
|
||||||
do_join_leave_group(struct api_msg_msg *msg)
|
do_join_leave_group(struct api_msg_msg *msg)
|
||||||
{
|
{
|
||||||
if (!ERR_IS_FATAL(msg->conn->err)) {
|
if (ERR_IS_FATAL(msg->conn->last_err)) {
|
||||||
|
msg->err = msg->conn->last_err;
|
||||||
|
} else {
|
||||||
if (msg->conn->pcb.tcp != NULL) {
|
if (msg->conn->pcb.tcp != NULL) {
|
||||||
if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
|
if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
|
||||||
#if LWIP_UDP
|
#if LWIP_UDP
|
||||||
if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
|
if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
|
||||||
msg->conn->err = igmp_joingroup(msg->msg.jl.interface, msg->msg.jl.multiaddr);
|
msg->err = igmp_joingroup(msg->msg.jl.interface, msg->msg.jl.multiaddr);
|
||||||
} else {
|
} else {
|
||||||
msg->conn->err = igmp_leavegroup(msg->msg.jl.interface, msg->msg.jl.multiaddr);
|
msg->err = igmp_leavegroup(msg->msg.jl.interface, msg->msg.jl.multiaddr);
|
||||||
}
|
}
|
||||||
#endif /* LWIP_UDP */
|
#endif /* LWIP_UDP */
|
||||||
#if (LWIP_TCP || LWIP_RAW)
|
#if (LWIP_TCP || LWIP_RAW)
|
||||||
} else {
|
} else {
|
||||||
msg->conn->err = ERR_VAL;
|
msg->err = ERR_VAL;
|
||||||
#endif /* (LWIP_TCP || LWIP_RAW) */
|
#endif /* (LWIP_TCP || LWIP_RAW) */
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
msg->err = ERR_CONN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TCPIP_APIMSG_ACK(msg);
|
TCPIP_APIMSG_ACK(msg);
|
||||||
|
@ -1440,8 +1440,9 @@ lwip_getsockopt_internal(void *arg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SO_ERROR:
|
case SO_ERROR:
|
||||||
|
/* only overwrite if ERR_OK before */
|
||||||
if (sock->err == 0) {
|
if (sock->err == 0) {
|
||||||
sock_set_errno(sock, err_to_errno(sock->conn->err));
|
sock_set_errno(sock, err_to_errno(sock->conn->last_err));
|
||||||
}
|
}
|
||||||
*(int *)optval = sock->err;
|
*(int *)optval = sock->err;
|
||||||
sock->err = 0;
|
sock->err = 0;
|
||||||
|
@ -274,13 +274,17 @@ err_t
|
|||||||
tcpip_apimsg(struct api_msg *apimsg)
|
tcpip_apimsg(struct api_msg *apimsg)
|
||||||
{
|
{
|
||||||
struct tcpip_msg msg;
|
struct tcpip_msg msg;
|
||||||
|
#ifdef LWIP_DEBUG
|
||||||
|
/* catch functions that don't set err */
|
||||||
|
apimsg->msg.err = ERR_VAL;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mbox != SYS_MBOX_NULL) {
|
if (mbox != SYS_MBOX_NULL) {
|
||||||
msg.type = TCPIP_MSG_API;
|
msg.type = TCPIP_MSG_API;
|
||||||
msg.msg.apimsg = apimsg;
|
msg.msg.apimsg = apimsg;
|
||||||
sys_mbox_post(mbox, &msg);
|
sys_mbox_post(mbox, &msg);
|
||||||
sys_arch_sem_wait(apimsg->msg.conn->op_completed, 0);
|
sys_arch_sem_wait(apimsg->msg.conn->op_completed, 0);
|
||||||
return ERR_OK;
|
return apimsg->msg.err;
|
||||||
}
|
}
|
||||||
return ERR_VAL;
|
return ERR_VAL;
|
||||||
}
|
}
|
||||||
@ -297,10 +301,15 @@ tcpip_apimsg(struct api_msg *apimsg)
|
|||||||
err_t
|
err_t
|
||||||
tcpip_apimsg_lock(struct api_msg *apimsg)
|
tcpip_apimsg_lock(struct api_msg *apimsg)
|
||||||
{
|
{
|
||||||
|
#ifdef LWIP_DEBUG
|
||||||
|
/* catch functions that don't set err */
|
||||||
|
apimsg->msg.err = ERR_VAL;
|
||||||
|
#endif
|
||||||
|
|
||||||
LOCK_TCPIP_CORE();
|
LOCK_TCPIP_CORE();
|
||||||
apimsg->function(&(apimsg->msg));
|
apimsg->function(&(apimsg->msg));
|
||||||
UNLOCK_TCPIP_CORE();
|
UNLOCK_TCPIP_CORE();
|
||||||
return ERR_OK;
|
return apimsg->msg.err;
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||||
|
Loading…
Reference in New Issue
Block a user