diff --git a/modules/network/SMSTCPIP/api_lib.c b/modules/network/SMSTCPIP/api_lib.c index 22010ee6c..1299b72d2 100644 --- a/modules/network/SMSTCPIP/api_lib.c +++ b/modules/network/SMSTCPIP/api_lib.c @@ -38,6 +38,7 @@ #include "lwip/api_msg.h" #include "lwip/memp.h" +#include #include #include @@ -72,17 +73,22 @@ void netbuf_delete(struct netbuf *buf) } /* end netbuf_delete */ -void netbuf_ref(struct netbuf *buf, void *dataptr, u16_t size) +err_t netbuf_ref(struct netbuf *buf, void *dataptr, u16_t size) { if (buf->p) pbuf_free(buf->p); buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); + if (buf->p == NULL) { + buf->ptr = NULL; + return ERR_MEM; + } buf->p->payload = dataptr; buf->p->len = buf->p->tot_len = size; buf->ptr = buf->p; + return ERR_OK; } /* end netbuf_ref */ void netbuf_copy_partial( @@ -434,7 +440,7 @@ netconn_recv(struct netconn *conn) if (p != NULL) { len = p->tot_len; - conn->recv_avail -= len; + SYS_ARCH_DEC(conn->recv_avail, len); } else len = 0; @@ -474,7 +480,7 @@ netconn_recv(struct netconn *conn) memp_free(MEMP_API_MSG, msg); } else { sys_mbox_fetch(conn->recvmbox, (void **)&buf); - conn->recv_avail -= buf->p->tot_len; + SYS_ARCH_DEC(conn->recv_avail, buf->p->tot_len); /* Register event with callback */ if (conn->callback) (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len); @@ -512,7 +518,7 @@ err_t netconn_send(struct netconn *conn, struct netbuf *buf) err_t netconn_write(struct netconn *conn, void *dataptr, u16_t size, u8_t copy) { struct api_msg *msg; - u16_t len; + u16_t len, sndbuf; if (conn == NULL) { return ERR_VAL; @@ -535,16 +541,16 @@ err_t netconn_write(struct netconn *conn, void *dataptr, u16_t size, u8_t copy) msg->msg.msg.w.copy = copy; if (conn->type == NETCONN_TCP) { - if (tcp_sndbuf(conn->pcb.tcp) == 0) { + while ((sndbuf = tcp_sndbuf(conn->pcb.tcp)) == 0) { sys_sem_wait(conn->sem); if (conn->err != ERR_OK) { goto ret; } } - if (size > tcp_sndbuf(conn->pcb.tcp)) { + if (size > sndbuf) { /* We cannot send more than one send buffer's worth of data at a time. */ - len = tcp_sndbuf(conn->pcb.tcp); + len = sndbuf; } else { len = size; } diff --git a/modules/network/SMSTCPIP/api_msg.c b/modules/network/SMSTCPIP/api_msg.c index cb5be00b7..c0712d60e 100644 --- a/modules/network/SMSTCPIP/api_msg.c +++ b/modules/network/SMSTCPIP/api_msg.c @@ -37,6 +37,7 @@ #include "lwip/sys.h" #include "lwip/tcpip.h" +#include #include #if LWIP_RAW @@ -61,7 +62,7 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, buf->fromaddr = addr; buf->fromport = pcb->protocol; - conn->recv_avail += p->tot_len; + SYS_ARCH_INC(conn->recv_avail, p->tot_len); /* Register event with callback */ if (conn->callback) (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, p->tot_len); @@ -97,7 +98,7 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, buf->fromport = port; } - conn->recv_avail += p->tot_len; + SYS_ARCH_INC(conn->recv_avail, p->tot_len); /* Register event with callback */ if (conn->callback) (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, p->tot_len); @@ -123,7 +124,7 @@ static err_t recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) if (p) { len = p->tot_len; - conn->recv_avail += len; + SYS_ARCH_INC(conn->recv_avail, len); } else len = 0; @@ -283,7 +284,7 @@ do_newconn(struct api_msg_msg *msg) /* This "new" connection already has a PCB allocated. */ /* Is this an error condition? Should it be deleted? We currently just are happy and return. */ - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); return; } @@ -340,7 +341,7 @@ do_newconn(struct api_msg_msg *msg) } - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); } @@ -392,7 +393,7 @@ do_delconn(struct api_msg_msg *msg) } if (msg->conn->mbox != SYS_MBOX_NULL) { - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); } } @@ -455,7 +456,7 @@ do_bind(struct api_msg_msg *msg) default: break; } - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); } #if LWIP_TCP @@ -495,7 +496,7 @@ do_connect(struct api_msg_msg *msg) msg->conn->pcb.udp = udp_new(); if (msg->conn->pcb.udp == NULL) { msg->conn->err = ERR_MEM; - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); return; } udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE); @@ -505,7 +506,7 @@ do_connect(struct api_msg_msg *msg) msg->conn->pcb.udp = udp_new(); if (msg->conn->pcb.udp == NULL) { msg->conn->err = ERR_MEM; - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); return; } udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); @@ -515,7 +516,7 @@ do_connect(struct api_msg_msg *msg) msg->conn->pcb.udp = udp_new(); if (msg->conn->pcb.udp == NULL) { msg->conn->err = ERR_MEM; - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); return; } udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn); @@ -526,7 +527,7 @@ do_connect(struct api_msg_msg *msg) msg->conn->pcb.tcp = tcp_new(); if (msg->conn->pcb.tcp == NULL) { msg->conn->err = ERR_MEM; - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); return; } #endif @@ -538,7 +539,7 @@ do_connect(struct api_msg_msg *msg) #if LWIP_RAW case NETCONN_RAW: raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr); - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); break; #endif #if LWIP_UDP @@ -548,7 +549,7 @@ do_connect(struct api_msg_msg *msg) /* FALLTHROUGH */ case NETCONN_UDP: udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); break; #endif #if LWIP_TCP @@ -589,7 +590,7 @@ do_disconnect(struct api_msg_msg *msg) default: break; } - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); } @@ -633,7 +634,7 @@ do_listen(struct api_msg_msg *msg) break; } } - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); } static void @@ -688,7 +689,7 @@ do_send(struct api_msg_msg *msg) break; } } - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); } static void do_recv(struct api_msg_msg *msg) @@ -733,7 +734,7 @@ do_write(struct api_msg_msg *msg) segments when new outgoing data arrives from the user if any previously transmitted data on the connection remains unacknowledged. */ - if (err == ERR_OK && (msg->conn->pcb.tcp->unacked == NULL || (msg->conn->pcb.tcp->flags & TF_NODELAY))) { + if (err == ERR_OK && (msg->conn->pcb.tcp->unacked == NULL || (msg->conn->pcb.tcp->flags & TF_NODELAY) || ( msg->conn->pcb.tcp->snd_queuelen) > 1)) { tcp_output(msg->conn->pcb.tcp); } msg->conn->err = err; @@ -747,7 +748,7 @@ do_write(struct api_msg_msg *msg) break; } } - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); } static void @@ -782,7 +783,7 @@ do_close(struct api_msg_msg *msg) break; } } - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg->conn->mbox); } api_msg_decode __decode__[API_MSG_MAX] = { diff --git a/modules/network/SMSTCPIP/include/lwip/api.h b/modules/network/SMSTCPIP/include/lwip/api.h index a450e282b..32f654dd0 100644 --- a/modules/network/SMSTCPIP/include/lwip/api.h +++ b/modules/network/SMSTCPIP/include/lwip/api.h @@ -76,7 +76,6 @@ struct netbuf struct pbuf *p, *ptr; struct ip_addr *fromaddr; u16_t fromport; - err_t err; }; struct netconn @@ -95,7 +94,7 @@ struct netconn sys_mbox_t acceptmbox; sys_sem_t sem; int socket; - u16_t recv_avail; + s16_t recv_avail; void (*callback)(struct netconn *, enum netconn_evt, u16_t len); }; @@ -104,7 +103,7 @@ struct netbuf *netbuf_new(void); void netbuf_delete(struct netbuf *buf); void *netbuf_alloc(struct netbuf *buf, u16_t size); void netbuf_free(struct netbuf *buf); -void netbuf_ref(struct netbuf *buf, +err_t netbuf_ref(struct netbuf *buf, void *dataptr, u16_t size); void netbuf_chain(struct netbuf *head, struct netbuf *tail); diff --git a/modules/network/SMSTCPIP/include/lwip/sys.h b/modules/network/SMSTCPIP/include/lwip/sys.h index d48efc4bd..6899c8fe1 100644 --- a/modules/network/SMSTCPIP/include/lwip/sys.h +++ b/modules/network/SMSTCPIP/include/lwip/sys.h @@ -151,4 +151,40 @@ unsigned long sys_now(void); #endif /* SYS_ARCH_PROTECT */ +#ifndef SYS_ARCH_INC +#define SYS_ARCH_INC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var += val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_INC */ + +#ifndef SYS_ARCH_DEC +#define SYS_ARCH_DEC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var -= val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_DEC */ + +#ifndef SYS_ARCH_GET +#define SYS_ARCH_GET(var, ret) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + ret = var; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_GET */ + +#ifndef SYS_ARCH_SET +#define SYS_ARCH_SET(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var = val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_SET */ + #endif /* __LWIP_SYS_H__ */ diff --git a/modules/network/SMSTCPIP/include/lwip/tcpip.h b/modules/network/SMSTCPIP/include/lwip/tcpip.h index ff25dcbe8..4f93c2cf4 100644 --- a/modules/network/SMSTCPIP/include/lwip/tcpip.h +++ b/modules/network/SMSTCPIP/include/lwip/tcpip.h @@ -43,9 +43,11 @@ extern sys_sem_t lock_tcpip_core; #define LOCK_TCPIP_CORE() sys_sem_wait(lock_tcpip_core) /** Unlock lwIP core mutex (needs @ref LWIP_TCPIP_CORE_LOCKING 1) */ #define UNLOCK_TCPIP_CORE() sys_sem_signal(lock_tcpip_core) +#define TCPIP_APIMSG_ACK(m) #else /* LWIP_TCPIP_CORE_LOCKING */ #define LOCK_TCPIP_CORE() #define UNLOCK_TCPIP_CORE() +#define TCPIP_APIMSG_ACK(m) sys_mbox_post(m, NULL) #endif /* LWIP_TCPIP_CORE_LOCKING */ void tcpip_init(void (*tcpip_init_done)(void *), void *arg); diff --git a/modules/network/SMSTCPIP/sockets.c b/modules/network/SMSTCPIP/sockets.c index 36012cc40..d75c32c3f 100644 --- a/modules/network/SMSTCPIP/sockets.c +++ b/modules/network/SMSTCPIP/sockets.c @@ -39,6 +39,7 @@ #include "lwip/sockets.h" +#include #include #include #include @@ -52,7 +53,7 @@ struct lwip_socket struct netconn *conn; struct netbuf *lastdata; u16_t lastoffset; - u16_t rcvevent; + s16_t rcvevent; u16_t sendevent; u16_t flags; int err; @@ -363,7 +364,7 @@ int lwip_recvfrom(int s, void *header, int index, void *payload, int plen, unsig buf = sock->lastdata; } else { /* If this is non-blocking call, then check first */ - if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK)) && !sock->rcvevent) { + if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK)) && (sock->rcvevent <= 0)) { LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s)); sock_set_errno(sock, EWOULDBLOCK); return -1; @@ -497,10 +498,10 @@ int lwip_send(int s, void *data, int size, unsigned int flags) /* make the buffer point to the data that should be sent */ - netbuf_ref(buf, data, size); - - /* send the data */ - err = netconn_send(sock->conn, buf); + if ((err = netbuf_ref(buf, data, size))==ERR_OK) { + /* send the data */ + err = netconn_send(sock->conn, buf); + } /* deallocated the buffer */ netbuf_delete(buf); @@ -627,7 +628,7 @@ lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset) if (FD_ISSET(i, readset)) { /* See if netconn of this socket is ready for read */ p_sock = get_socket(i); - if (p_sock && (p_sock->lastdata || p_sock->rcvevent)) { + if (p_sock && (p_sock->lastdata || (p_sock->rcvevent > 0))) { FD_SET(i, &lreadset); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); nready++; @@ -744,7 +745,7 @@ int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptse sys_sem_signal(selectsem); sys_sem_free(select_cb.sem); - if (i == 0) /* Timeout */ + if (i == SYS_ARCH_TIMEOUT) /* Timeout */ { if (readset) FD_ZERO(readset); @@ -852,7 +853,7 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) if (scb->sem_signalled == 0) { /* Test this select call for our socket */ if (scb->readset && FD_ISSET(s, scb->readset)) - if (sock->rcvevent) + if (sock->rcvevent > 0) break; if (scb->writeset && FD_ISSET(s, scb->writeset)) if (sock->sendevent) @@ -861,8 +862,8 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) } if (scb) { scb->sem_signalled = 1; - sys_sem_signal(selectsem); sys_sem_signal(scb->sem); + sys_sem_signal(selectsem); } else { sys_sem_signal(selectsem); break; @@ -1348,7 +1349,7 @@ int lwip_ioctl(int s, long cmd, void *argp) return -1; } - *((u16_t *)argp) = sock->conn->recv_avail; + SYS_ARCH_GET(sock->conn->recv_avail, *((u16_t*)argp)); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %u\n", s, argp, *((u16_t *)argp))); sock_set_errno(sock, 0);