diff options
| author | bernard.xiong <[email protected]> | 2009-09-06 11:04:38 +0000 |
|---|---|---|
| committer | bernard.xiong <[email protected]> | 2009-09-06 11:04:38 +0000 |
| commit | b9290bcef45a9ebc088e1f20596b7e02c7ca47f6 (patch) | |
| tree | d3545a00a8b25782bf32c52f491df1188abdcfee /net/lwip/src/api | |
| parent | 1ae9da2752f5ae98d029dce078c49f2a5364019c (diff) | |
update lwip to 1.3.1
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@37 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'net/lwip/src/api')
| -rw-r--r-- | net/lwip/src/api/api_lib.c | 17 | ||||
| -rw-r--r-- | net/lwip/src/api/api_msg.c | 70 | ||||
| -rw-r--r-- | net/lwip/src/api/err.c | 22 | ||||
| -rw-r--r-- | net/lwip/src/api/netbuf.c | 4 | ||||
| -rw-r--r-- | net/lwip/src/api/netdb.c | 22 | ||||
| -rw-r--r-- | net/lwip/src/api/sockets.c | 315 | ||||
| -rw-r--r-- | net/lwip/src/api/tcpip.c | 85 |
7 files changed, 335 insertions, 200 deletions
diff --git a/net/lwip/src/api/api_lib.c b/net/lwip/src/api/api_lib.c index 22b65a315d..86df911ea3 100644 --- a/net/lwip/src/api/api_lib.c +++ b/net/lwip/src/api/api_lib.c @@ -120,19 +120,6 @@ netconn_delete(struct netconn *conn) } /** - * Get the type of a netconn (as enum netconn_type). - * - * @param conn the netconn of which to get the type - * @return the netconn_type of conn - */ -enum netconn_type -netconn_type(struct netconn *conn) -{ - LWIP_ERROR("netconn_type: invalid conn", (conn != NULL), return NETCONN_INVALID;); - return conn->type; -} - -/** * Get the local or remote IP address and port of a netconn. * For RAW netconns, this returns the protocol instead of a port! * @@ -439,7 +426,7 @@ netconn_send(struct netconn *conn, struct netbuf *buf) LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;); - LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %d bytes\n", buf->p->tot_len)); + LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len)); msg.function = do_send; msg.msg.conn = conn; msg.msg.msg.b = buf; @@ -459,7 +446,7 @@ netconn_send(struct netconn *conn, struct netbuf *buf) * @return ERR_OK if data was sent, any other err_t on error */ err_t -netconn_write(struct netconn *conn, const void *dataptr, int size, u8_t apiflags) +netconn_write(struct netconn *conn, const void *dataptr, size_t size, u8_t apiflags) { struct api_msg msg; diff --git a/net/lwip/src/api/api_msg.c b/net/lwip/src/api/api_msg.c index 04646a5405..28d1010193 100644 --- a/net/lwip/src/api/api_msg.c +++ b/net/lwip/src/api/api_msg.c @@ -52,6 +52,8 @@ #include "lwip/igmp.h" #include "lwip/dns.h" +#include <string.h> + /* forward declarations */ #if LWIP_TCP static err_t do_writemore(struct netconn *conn); @@ -108,11 +110,13 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, buf->addr = &(((struct ip_hdr*)(q->payload))->src); buf->port = pcb->protocol; - SYS_ARCH_INC(conn->recv_avail, q->tot_len); - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, q->tot_len); if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) { netbuf_delete(buf); + return 0; + } else { + SYS_ARCH_INC(conn->recv_avail, q->tot_len); + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, q->tot_len); } } } @@ -166,12 +170,13 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, buf->port = port; } - SYS_ARCH_INC(conn->recv_avail, p->tot_len); - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len); if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) { netbuf_delete(buf); return; + } else { + SYS_ARCH_INC(conn->recv_avail, p->tot_len); + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len); } } #endif /* LWIP_UDP */ @@ -206,10 +211,12 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) } else { len = 0; } - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + if (sys_mbox_trypost(conn->recvmbox, p) != ERR_OK) { return ERR_MEM; + } else { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); } return ERR_OK; @@ -365,8 +372,6 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) newconn->pcb.tcp = newpcb; setup_tcp(newconn); newconn->err = err; - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); if (sys_mbox_trypost(conn->acceptmbox, newconn) != ERR_OK) { /* When returning != ERR_OK, the connection is aborted in tcp_process(), @@ -374,7 +379,11 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) newconn->pcb.tcp = NULL; netconn_free(newconn); return ERR_MEM; + } else { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); } + return ERR_OK; } #endif /* LWIP_TCP */ @@ -528,11 +537,18 @@ netconn_alloc(enum netconn_type t, netconn_callback callback) conn->socket = -1; conn->callback = callback; conn->recv_avail = 0; +#if LWIP_TCP + conn->write_msg = NULL; + conn->write_offset = 0; +#if LWIP_TCPIP_CORE_LOCKING + conn->write_delayed = 0; +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_TCP */ #if LWIP_SO_RCVTIMEO conn->recv_timeout = 0; #endif /* LWIP_SO_RCVTIMEO */ #if LWIP_SO_RCVBUF - conn->recv_bufsize = INT_MAX; + conn->recv_bufsize = RECV_BUFSIZE_DEFAULT; #endif /* LWIP_SO_RCVBUF */ return conn; } @@ -598,11 +614,16 @@ do_close_internal(struct netconn *conn) LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL)); /* Set back some callback pointers */ + tcp_arg(conn->pcb.tcp, NULL); if (conn->pcb.tcp->state == LISTEN) { - tcp_arg(conn->pcb.tcp, NULL); tcp_accept(conn->pcb.tcp, NULL); } else { tcp_recv(conn->pcb.tcp, NULL); + tcp_accept(conn->pcb.tcp, NULL); + /* some callbacks have to be reset if tcp_close is not successful */ + tcp_sent(conn->pcb.tcp, NULL); + tcp_poll(conn->pcb.tcp, NULL, 4); + tcp_err(conn->pcb.tcp, NULL); } /* Try to close the connection */ err = tcp_close(conn->pcb.tcp); @@ -610,11 +631,6 @@ do_close_internal(struct netconn *conn) /* Closing succeeded */ conn->state = NETCONN_NONE; /* Set back some callback pointers as conn is going away */ - tcp_err(conn->pcb.tcp, NULL); - tcp_poll(conn->pcb.tcp, NULL, 4); - tcp_sent(conn->pcb.tcp, NULL); - tcp_recv(conn->pcb.tcp, NULL); - tcp_arg(conn->pcb.tcp, NULL); conn->pcb.tcp = NULL; conn->err = ERR_OK; /* Trigger select() in socket layer. This send should something else so the @@ -623,6 +639,14 @@ do_close_internal(struct netconn *conn) API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); /* wake up the application task */ sys_sem_signal(conn->op_completed); + } else { + /* Closing failed, restore some of the callbacks */ + /* Closing of listen pcb will never fail! */ + LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN)); + tcp_sent(conn->pcb.tcp, sent_tcp); + tcp_poll(conn->pcb.tcp, poll_tcp, 4); + tcp_err(conn->pcb.tcp, err_tcp); + tcp_arg(conn->pcb.tcp, conn); } /* If closing didn't succeed, we get called again either from poll_tcp or from sent_tcp */ @@ -894,7 +918,7 @@ do_send(struct api_msg_msg *msg) } /** - * Recv some data from a RAW or UDP pcb contained in a netconn + * Indicate data has been received from a TCP pcb contained in a netconn * Called from netconn_recv * * @param msg the api_msg_msg pointing to the connection @@ -940,17 +964,19 @@ do_writemore(struct netconn *conn) void *dataptr; u16_t len, available; u8_t write_finished = 0; + size_t diff; LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE)); dataptr = (u8_t*)conn->write_msg->msg.w.dataptr + conn->write_offset; - if ((conn->write_msg->msg.w.len - conn->write_offset > 0xffff)) { /* max_u16_t */ + diff = conn->write_msg->msg.w.len - conn->write_offset; + if (diff > 0xffffUL) { /* max_u16_t */ len = 0xffff; #if LWIP_TCPIP_CORE_LOCKING conn->write_delayed = 1; #endif } else { - len = conn->write_msg->msg.w.len - conn->write_offset; + len = (u16_t)diff; } available = tcp_sndbuf(conn->pcb.tcp); if (available < len) { @@ -970,6 +996,8 @@ do_writemore(struct netconn *conn) write_finished = 1; conn->write_msg = NULL; 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); conn->err = err; @@ -1027,6 +1055,8 @@ do_write(struct api_msg_msg *msg) #if LWIP_TCP msg->conn->state = NETCONN_WRITE; /* set all the variables used by do_writemore */ + LWIP_ASSERT("already writing", msg->conn->write_msg == NULL && + msg->conn->write_offset == 0); msg->conn->write_msg = msg; msg->conn->write_offset = 0; #if LWIP_TCPIP_CORE_LOCKING diff --git a/net/lwip/src/api/err.c b/net/lwip/src/api/err.c index a803a729da..a90cb98c82 100644 --- a/net/lwip/src/api/err.c +++ b/net/lwip/src/api/err.c @@ -44,17 +44,17 @@ static const char *err_strerr[] = { "Ok.", /* ERR_OK 0 */ "Out of memory error.", /* ERR_MEM -1 */ "Buffer error.", /* ERR_BUF -2 */ - "Routing problem.", /* ERR_RTE -3 */ - "Connection aborted.", /* ERR_ABRT -4 */ - "Connection reset.", /* ERR_RST -5 */ - "Connection closed.", /* ERR_CLSD -6 */ - "Not connected.", /* ERR_CONN -7 */ - "Illegal value.", /* ERR_VAL -8 */ - "Illegal argument.", /* ERR_ARG -9 */ - "Address in use.", /* ERR_USE -10 */ - "Low-level netif error.", /* ERR_IF -11 */ - "Already connected.", /* ERR_ISCONN -12 */ - "Timeout.", /* ERR_TIMEOUT -13 */ + "Timeout.", /* ERR_TIMEOUT -3 */ + "Routing problem.", /* ERR_RTE -4 */ + "Connection aborted.", /* ERR_ABRT -5 */ + "Connection reset.", /* ERR_RST -6 */ + "Connection closed.", /* ERR_CLSD -7 */ + "Not connected.", /* ERR_CONN -8 */ + "Illegal value.", /* ERR_VAL -9 */ + "Illegal argument.", /* ERR_ARG -10 */ + "Address in use.", /* ERR_USE -11 */ + "Low-level netif error.", /* ERR_IF -12 */ + "Already connected.", /* ERR_ISCONN -13 */ "Operation in progress." /* ERR_INPROGRESS -14 */ }; diff --git a/net/lwip/src/api/netbuf.c b/net/lwip/src/api/netbuf.c index 27120eb519..af44eefc7e 100644 --- a/net/lwip/src/api/netbuf.c +++ b/net/lwip/src/api/netbuf.c @@ -158,14 +158,14 @@ netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size) * Chain one netbuf to another (@see pbuf_chain) * * @param head the first netbuf - * @param tail netbuf to chain after head + * @param tail netbuf to chain after head, freed by this function, may not be reference after returning */ void netbuf_chain(struct netbuf *head, struct netbuf *tail) { LWIP_ERROR("netbuf_ref: invalid head", (head != NULL), return;); LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;); - pbuf_chain(head->p, tail->p); + pbuf_cat(head->p, tail->p); head->ptr = head->p; memp_free(MEMP_NETBUF, tail); } diff --git a/net/lwip/src/api/netdb.c b/net/lwip/src/api/netdb.c index d1f134ce7d..8aa237f4c1 100644 --- a/net/lwip/src/api/netdb.c +++ b/net/lwip/src/api/netdb.c @@ -42,6 +42,9 @@ #include "lwip/ip_addr.h" #include "lwip/api.h" +#include <string.h> +#include <stdlib.h> + /** helper struct for gethostbyname_r to access the char* buffer */ struct gethostbyname_r_helper { struct ip_addr *addrs; @@ -107,23 +110,23 @@ lwip_gethostbyname(const char *name) #if DNS_DEBUG /* dump hostent */ - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name)); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == 0x%08lX\n",(u32_t)(s_hostent.h_aliases))); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == %p\n", s_hostent.h_aliases)); if (s_hostent.h_aliases != NULL) { u8_t idx; for ( idx=0; s_hostent.h_aliases[idx]; idx++) { - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == 0x%08lX\n", idx, s_hostent.h_aliases[idx])); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %p\n", idx, s_hostent.h_aliases[idx])); LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %s\n", idx, s_hostent.h_aliases[idx])); } } - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %lu\n", (u32_t)(s_hostent.h_addrtype))); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %lu\n", (u32_t)(s_hostent.h_length))); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == 0x%08lX\n", s_hostent.h_addr_list)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %d\n", s_hostent.h_length)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == %p\n", s_hostent.h_addr_list)); if (s_hostent.h_addr_list != NULL) { u8_t idx; for ( idx=0; s_hostent.h_addr_list[idx]; idx++) { - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == 0x%08lX\n", idx, s_hostent.h_addr_list[idx])); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, inet_ntoa(*((struct in_addr*)(s_hostent.h_addr_list[idx]))))); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx])); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, inet_ntoa(*((struct in_addr*)(s_hostent.h_addr_list[idx]))))); } } #endif /* DNS_DEBUG */ @@ -326,7 +329,8 @@ lwip_getaddrinfo(const char *nodename, const char *servname, if (nodename != NULL) { /* copy nodename to canonname if specified */ size_t namelen = strlen(nodename); - ai->ai_canonname = mem_malloc(namelen + 1); + LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1); + ai->ai_canonname = mem_malloc((mem_size_t)(namelen + 1)); if (ai->ai_canonname == NULL) { goto memerr; } diff --git a/net/lwip/src/api/sockets.c b/net/lwip/src/api/sockets.c index 58c8e265df..f177261e10 100644 --- a/net/lwip/src/api/sockets.c +++ b/net/lwip/src/api/sockets.c @@ -66,7 +66,7 @@ struct lwip_socket { u16_t lastoffset; /** number of times data was received, set by event_callback(), tested by the receive and select functions */ - u16_t rcvevent; + s16_t rcvevent; /** number of times data was received, set by event_callback(), tested by select */ u16_t sendevent; @@ -128,17 +128,17 @@ static const int err_to_errno_table[] = { 0, /* ERR_OK 0 No error, everything OK. */ ENOMEM, /* ERR_MEM -1 Out of memory error. */ ENOBUFS, /* ERR_BUF -2 Buffer error. */ - EHOSTUNREACH, /* ERR_RTE -3 Routing problem. */ - ECONNABORTED, /* ERR_ABRT -4 Connection aborted. */ - ECONNRESET, /* ERR_RST -5 Connection reset. */ - ESHUTDOWN, /* ERR_CLSD -6 Connection closed. */ - ENOTCONN, /* ERR_CONN -7 Not connected. */ - EINVAL, /* ERR_VAL -8 Illegal value. */ - EIO, /* ERR_ARG -9 Illegal argument. */ - EADDRINUSE, /* ERR_USE -10 Address in use. */ - -1, /* ERR_IF -11 Low-level netif error */ - -1, /* ERR_ISCONN -12 Already connected. */ - ETIMEDOUT, /* ERR_TIMEOUT -13 Timeout */ + ETIMEDOUT, /* ERR_TIMEOUT -3 Timeout */ + EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ + ECONNABORTED, /* ERR_ABRT -5 Connection aborted. */ + ECONNRESET, /* ERR_RST -6 Connection reset. */ + ESHUTDOWN, /* ERR_CLSD -7 Connection closed. */ + ENOTCONN, /* ERR_CONN -8 Not connected. */ + EINVAL, /* ERR_VAL -9 Illegal value. */ + EIO, /* ERR_ARG -10 Illegal argument. */ + EADDRINUSE, /* ERR_USE -11 Address in use. */ + -1, /* ERR_IF -12 Low-level netif error */ + -1, /* ERR_ISCONN -13 Already connected. */ EINPROGRESS /* ERR_INPROGRESS -14 Operation in progress */ }; @@ -150,7 +150,9 @@ static const int err_to_errno_table[] = { err_to_errno_table[-(err)] : EIO) #ifdef ERRNO +#ifndef set_errno #define set_errno(err) errno = (err) +#endif #else #define set_errno(err) #endif @@ -258,6 +260,12 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) if (!sock) return -1; + if ((sock->flags & O_NONBLOCK) && (sock->rcvevent <= 0)) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s)); + sock_set_errno(sock, EWOULDBLOCK); + return -1; + } + newconn = netconn_accept(sock->conn); if (!newconn) { LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) failed, err=%d\n", s, sock->conn->err)); @@ -273,16 +281,22 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) return -1; } - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(sin); - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - sin.sin_addr.s_addr = naddr.addr; + /* Note that POSIX only requires us to check addr is non-NULL. addrlen must + * not be NULL if addr is valid. + */ + if (NULL != addr) { + LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL); + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + sin.sin_addr.s_addr = naddr.addr; - if (*addrlen > sizeof(sin)) - *addrlen = sizeof(sin); + if (*addrlen > sizeof(sin)) + *addrlen = sizeof(sin); - SMEMCPY(addr, &sin, *addrlen); + MEMCPY(addr, &sin, *addrlen); + } newsock = alloc_socket(newconn); if (newsock == -1) { @@ -307,14 +321,14 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); ip_addr_debug_print(SOCKETS_DEBUG, &naddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", port)); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port)); sock_set_errno(sock, 0); return newsock; } int -lwip_bind(int s, struct sockaddr *name, socklen_t namelen) +lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) { struct lwip_socket *sock; struct ip_addr local_addr; @@ -326,15 +340,15 @@ lwip_bind(int s, struct sockaddr *name, socklen_t namelen) return -1; LWIP_ERROR("lwip_bind: invalid address", ((namelen == sizeof(struct sockaddr_in)) && - ((((struct sockaddr_in *)name)->sin_family) == AF_INET)), + ((((const struct sockaddr_in *)name)->sin_family) == AF_INET)), sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - local_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr; - local_port = ((struct sockaddr_in *)name)->sin_port; + local_addr.addr = ((const struct sockaddr_in *)name)->sin_addr.s_addr; + local_port = ((const struct sockaddr_in *)name)->sin_port; LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); ip_addr_debug_print(SOCKETS_DEBUG, &local_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(local_port))); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(local_port))); err = netconn_bind(sock->conn, &local_addr, ntohs(local_port)); @@ -386,22 +400,22 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) return -1; LWIP_ERROR("lwip_connect: invalid address", ((namelen == sizeof(struct sockaddr_in)) && - ((((struct sockaddr_in *)name)->sin_family) == AF_INET)), + ((((const struct sockaddr_in *)name)->sin_family) == AF_INET)), sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - if (((struct sockaddr_in *)name)->sin_family == AF_UNSPEC) { + if (((const struct sockaddr_in *)name)->sin_family == AF_UNSPEC) { LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); err = netconn_disconnect(sock->conn); } else { struct ip_addr remote_addr; u16_t remote_port; - remote_addr.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr; - remote_port = ((struct sockaddr_in *)name)->sin_port; + remote_addr.addr = ((const struct sockaddr_in *)name)->sin_addr.s_addr; + remote_port = ((const struct sockaddr_in *)name)->sin_port; LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u)\n", ntohs(remote_port))); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(remote_port))); err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); } @@ -458,7 +472,7 @@ lwip_listen(int s, int backlog) } int -lwip_recvfrom(int s, void *mem, int len, unsigned int flags, +lwip_recvfrom(int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) { struct lwip_socket *sock; @@ -468,7 +482,7 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags, u16_t port; u8_t done = 0; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %d, 0x%x, ..)\n", s, mem, len, flags)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags)); sock = get_socket(s); if (!sock) return -1; @@ -480,7 +494,13 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags, 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)) { + if (off > 0) { + /* already received data, return that */ + sock_set_errno(sock, 0); + return off; + } LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s)); sock_set_errno(sock, EWOULDBLOCK); return -1; @@ -492,22 +512,29 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags, LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: netconn_recv netbuf=%p\n", (void*)buf)); if (!buf) { + if (off > 0) { + /* already received data, return that */ + sock_set_errno(sock, 0); + return off; + } /* We should really do some error checking here. */ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s)); - sock_set_errno(sock, (((sock->conn->pcb.ip!=NULL) && (sock->conn->err==ERR_OK))?ETIMEDOUT:err_to_errno(sock->conn->err))); + sock_set_errno(sock, (((sock->conn->pcb.ip != NULL) && (sock->conn->err == ERR_OK)) + ? ETIMEDOUT : err_to_errno(sock->conn->err))); return 0; } } buflen = netbuf_len(buf); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%d len=%d off=%d sock->lastoffset=%d\n", buflen, len, off, sock->lastoffset)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%"U16_F" len=%"SZT_F" off=%"U16_F" sock->lastoffset=%"U16_F"\n", + buflen, len, off, sock->lastoffset)); buflen -= sock->lastoffset; if (len > buflen) { copylen = buflen; } else { - copylen = len; + copylen = (u16_t)len; } /* copy the contents of the received buffer into @@ -517,20 +544,71 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags, off += copylen; if (netconn_type(sock->conn) == NETCONN_TCP) { + LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen); len -= copylen; - if ( (len <= 0) || (buf->p->flags & PBUF_FLAG_PUSH) || !sock->rcvevent) { + if ( (len <= 0) || + (buf->p->flags & PBUF_FLAG_PUSH) || + (sock->rcvevent <= 0) || + ((flags & MSG_PEEK)!=0)) { done = 1; } } else { done = 1; } + /* Check to see from where the data was.*/ + if (done) { + if (from && fromlen) { + struct sockaddr_in sin; + + if (netconn_type(sock->conn) == NETCONN_TCP) { + addr = (struct ip_addr*)&(sin.sin_addr.s_addr); + netconn_getaddr(sock->conn, addr, &port, 0); + } else { + addr = netbuf_fromaddr(buf); + port = netbuf_fromport(buf); + } + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + sin.sin_addr.s_addr = addr->addr; + + if (*fromlen > sizeof(sin)) { + *fromlen = sizeof(sin); + } + + MEMCPY(from, &sin, *fromlen); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%"U16_F"\n", port, off)); + } else { + #if SOCKETS_DEBUG + struct sockaddr_in sin; + + if (netconn_type(sock->conn) == NETCONN_TCP) { + addr = (struct ip_addr*)&(sin.sin_addr.s_addr); + netconn_getaddr(sock->conn, addr, &port, 0); + } else { + addr = netbuf_fromaddr(buf); + port = netbuf_fromport(buf); + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%"U16_F"\n", port, off)); + #endif /* SOCKETS_DEBUG */ + } + } + /* If we don't peek the incoming message... */ if ((flags & MSG_PEEK)==0) { /* If this is a TCP socket, check if there is data left in the buffer. If so, it should be saved in the sock structure for next time around. */ - if ((sock->conn->type == NETCONN_TCP) && (buflen - copylen > 0)) { + if ((netconn_type(sock->conn) == NETCONN_TCP) && (buflen - copylen > 0)) { sock->lastdata = buf; sock->lastoffset += copylen; LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now netbuf=%p\n", (void*)buf)); @@ -540,85 +618,39 @@ lwip_recvfrom(int s, void *mem, int len, unsigned int flags, LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", (void*)buf)); netbuf_delete(buf); } - } else { - done = 1; } } while (!done); - /* Check to see from where the data was.*/ - if (from && fromlen) { - struct sockaddr_in sin; - - if (netconn_type(sock->conn) == NETCONN_TCP) { - addr = (struct ip_addr*)&(sin.sin_addr.s_addr); - netconn_getaddr(sock->conn, addr, &port, 0); - } else { - addr = netbuf_fromaddr(buf); - port = netbuf_fromport(buf); - } - - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(sin); - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - sin.sin_addr.s_addr = addr->addr; - - if (*fromlen > sizeof(sin)) - *fromlen = sizeof(sin); - - SMEMCPY(from, &sin, *fromlen); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); - ip_addr_debug_print(SOCKETS_DEBUG, addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, off)); - } else { -#if SOCKETS_DEBUG - struct sockaddr_in sin; - - if (netconn_type(sock->conn) == NETCONN_TCP) { - addr = (struct ip_addr*)&(sin.sin_addr.s_addr); - netconn_getaddr(sock->conn, addr, &port, 0); - } else { - addr = netbuf_fromaddr(buf); - port = netbuf_fromport(buf); - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); - ip_addr_debug_print(SOCKETS_DEBUG, addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u len=%u\n", port, off)); -#endif /* SOCKETS_DEBUG */ - } - sock_set_errno(sock, 0); return off; } int -lwip_read(int s, void *mem, int len) +lwip_read(int s, void *mem, size_t len) { return lwip_recvfrom(s, mem, len, 0, NULL, NULL); } int -lwip_recv(int s, void *mem, int len, unsigned int flags) +lwip_recv(int s, void *mem, size_t len, int flags) { return lwip_recvfrom(s, mem, len, flags, NULL, NULL); } int -lwip_send(int s, const void *data, int size, unsigned int flags) +lwip_send(int s, const void *data, size_t size, int flags) { struct lwip_socket *sock; err_t err; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%d, flags=0x%x)\n", + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n", s, data, size, flags)); sock = get_socket(s); if (!sock) return -1; - if (sock->conn->type!=NETCONN_TCP) { + if (sock->conn->type != NETCONN_TCP) { #if (LWIP_UDP || LWIP_RAW) return lwip_sendto(s, data, size, flags, NULL, 0); #else @@ -629,18 +661,19 @@ lwip_send(int s, const void *data, int size, unsigned int flags) err = netconn_write(sock->conn, data, size, NETCONN_COPY | ((flags & MSG_MORE)?NETCONN_MORE:0)); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d size=%d\n", s, err, size)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d size=%"SZT_F"\n", s, err, size)); sock_set_errno(sock, err_to_errno(err)); - return (err==ERR_OK?size:-1); + return (err == ERR_OK ? (int)size : -1); } int -lwip_sendto(int s, const void *data, int size, unsigned int flags, - struct sockaddr *to, socklen_t tolen) +lwip_sendto(int s, const void *data, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) { struct lwip_socket *sock; struct ip_addr remote_addr; - int err; + err_t err; + u16_t short_size; #if !LWIP_TCPIP_CORE_LOCKING struct netbuf buf; u16_t remote_port; @@ -650,7 +683,7 @@ lwip_sendto(int s, const void *data, int size, unsigned int flags, if (!sock) return -1; - if (sock->conn->type==NETCONN_TCP) { + if (sock->conn->type == NETCONN_TCP) { #if LWIP_TCP return lwip_send(s, data, size, flags); #else @@ -659,11 +692,11 @@ lwip_sendto(int s, const void *data, int size, unsigned int flags, #endif /* LWIP_TCP */ } - LWIP_ASSERT("lwip_sendto: size must fit in u16_t", - ((size >= 0) && (size <= 0xffff))); + LWIP_ASSERT("lwip_sendto: size must fit in u16_t", size <= 0xffff); + short_size = (u16_t)size; LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) || ((tolen == sizeof(struct sockaddr_in)) && - ((((struct sockaddr_in *)to)->sin_family) == AF_INET))), + ((((const struct sockaddr_in *)to)->sin_family) == AF_INET))), sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); #if LWIP_TCPIP_CORE_LOCKING @@ -675,15 +708,15 @@ lwip_sendto(int s, const void *data, int size, unsigned int flags, err = ERR_MEM; } else { p->payload = (void*)data; - p->len = p->tot_len = size; + p->len = p->tot_len = short_size; - remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr; + remote_addr.addr = ((const struct sockaddr_in *)to)->sin_addr.s_addr; LOCK_TCPIP_CORE(); if (sock->conn->type==NETCONN_RAW) { err = sock->conn->err = raw_sendto(sock->conn->pcb.raw, p, &remote_addr); } else { - err = sock->conn->err = udp_sendto(sock->conn->pcb.udp, p, &remote_addr, ntohs(((struct sockaddr_in *)to)->sin_port)); + err = sock->conn->err = udp_sendto(sock->conn->pcb.udp, p, &remote_addr, ntohs(((const struct sockaddr_in *)to)->sin_port)); } UNLOCK_TCPIP_CORE(); @@ -694,8 +727,8 @@ lwip_sendto(int s, const void *data, int size, unsigned int flags, /* initialize a buffer */ buf.p = buf.ptr = NULL; if (to) { - remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr; - remote_port = ntohs(((struct sockaddr_in *)to)->sin_port); + remote_addr.addr = ((const struct sockaddr_in *)to)->sin_addr.s_addr; + remote_port = ntohs(((const struct sockaddr_in *)to)->sin_port); buf.addr = &remote_addr; buf.port = remote_port; } else { @@ -705,24 +738,32 @@ lwip_sendto(int s, const void *data, int size, unsigned int flags, buf.port = 0; } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, size=%d, flags=0x%x to=", - s, data, size, flags)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%d"U16_F", flags=0x%x to=", + s, data, short_size, flags)); ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%u\n", remote_port)); - + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port)); + /* make the buffer point to the data that should be sent */ - if ((err = netbuf_ref(&buf, data, size)) == ERR_OK) { +#if LWIP_NETIF_TX_SINGLE_PBUF + /* Allocate a new netbuf and copy the data into it. */ + if (netbuf_alloc(&buf, short_size) == NULL) { + err = ERR_MEM; + } else { + err = netbuf_take(&buf, data, short_size); + } +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + err = netbuf_ref(&buf, data, short_size); +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + if (err == ERR_OK) { /* send the data */ err = netconn_send(sock->conn, &buf); } /* deallocated the buffer */ - if (buf.p != NULL) { - pbuf_free(buf.p); - } + netbuf_free(&buf); #endif /* LWIP_TCPIP_CORE_LOCKING */ sock_set_errno(sock, err_to_errno(err)); - return (err==ERR_OK?size:-1); + return (err == ERR_OK ? short_size : -1); } int @@ -778,7 +819,7 @@ lwip_socket(int domain, int type, int protocol) } int -lwip_write(int s, const void *data, int size) +lwip_write(int s, const void *data, size_t size) { return lwip_send(s, data, size, 0); } @@ -815,7 +856,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++; @@ -855,7 +896,8 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n", maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, - timeout ? timeout->tv_sec : -1L, timeout ? timeout->tv_usec : -1L)); + timeout ? (long)timeout->tv_sec : (long)-1, + timeout ? (long)timeout->tv_usec : (long)-1)); select_cb.next = 0; select_cb.readset = readset; @@ -923,15 +965,8 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, if(msectimeout == 0) msectimeout = 1; } - - if (msectimeout > 0 && sys_arch_timeouts() == NULL){ - /* it's not a lwip thread, use os semaphore with timeout to handle it */ - i = sys_arch_sem_wait(select_cb.sem, msectimeout); - } - else { - /* it's a lwip thread, use os semaphore with timeout to handle it */ - i = sys_sem_wait_timeout(select_cb.sem, msectimeout); - } + + i = sys_sem_wait_timeout(select_cb.sem, msectimeout); /* Take us off the list */ sys_sem_wait(selectsem); @@ -1069,7 +1104,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) @@ -1078,8 +1113,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; @@ -1119,7 +1154,7 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); ip_addr_debug_print(SOCKETS_DEBUG, &naddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%d)\n", sin.sin_port)); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", sin.sin_port)); sin.sin_port = htons(sin.sin_port); sin.sin_addr.s_addr = naddr.addr; @@ -1127,7 +1162,7 @@ lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) if (*namelen > sizeof(sin)) *namelen = sizeof(sin); - SMEMCPY(name, &sin, *namelen); + MEMCPY(name, &sin, *namelen); sock_set_errno(sock, 0); return 0; } @@ -1444,7 +1479,7 @@ lwip_getsockopt_internal(void *arg) break; case IP_MULTICAST_IF: ((struct in_addr*) optval)->s_addr = sock->conn->pcb.udp->multicast_ip.addr; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%x\n", + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n", s, *(u32_t *)optval)); break; #endif /* LWIP_IGMP */ @@ -1777,12 +1812,12 @@ lwip_setsockopt_internal(void *arg) switch (optname) { case IP_TTL: sock->conn->pcb.ip->ttl = (u8_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %u\n", + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n", s, sock->conn->pcb.ip->ttl)); break; case IP_TOS: sock->conn->pcb.ip->tos = (u8_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %u\n", + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", s, sock->conn->pcb.ip->tos)); break; #if LWIP_IGMP @@ -1826,24 +1861,24 @@ lwip_setsockopt_internal(void *arg) break; case TCP_KEEPALIVE: sock->conn->pcb.tcp->keep_idle = (u32_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %lu\n", + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n", s, sock->conn->pcb.tcp->keep_idle)); break; #if LWIP_TCP_KEEPALIVE case TCP_KEEPIDLE: sock->conn->pcb.tcp->keep_idle = 1000*(u32_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %lu\n", + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n", s, sock->conn->pcb.tcp->keep_idle)); break; case TCP_KEEPINTVL: sock->conn->pcb.tcp->keep_intvl = 1000*(u32_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %lu\n", + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n", s, sock->conn->pcb.tcp->keep_intvl)); break; case TCP_KEEPCNT: sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %lu\n", + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n", s, sock->conn->pcb.tcp->keep_cnt)); break; #endif /* LWIP_TCP_KEEPALIVE */ @@ -1887,6 +1922,7 @@ lwip_ioctl(int s, long cmd, void *argp) { struct lwip_socket *sock = get_socket(s); u16_t buflen = 0; + s16_t recv_avail; if (!sock) return -1; @@ -1898,7 +1934,10 @@ lwip_ioctl(int s, long cmd, void *argp) return -1; } - SYS_ARCH_GET(sock->conn->recv_avail, *((u16_t*)argp)); + SYS_ARCH_GET(sock->conn->recv_avail, recv_avail); + if (recv_avail < 0) + recv_avail = 0; + *((u16_t*)argp) = (u16_t)recv_avail; /* Check if there is data left from the last recv operation. /maq 041215 */ if (sock->lastdata) { @@ -1908,7 +1947,7 @@ lwip_ioctl(int s, long cmd, void *argp) *((u16_t*)argp) += buflen; } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %u\n", s, argp, *((u16_t*)argp))); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp))); sock_set_errno(sock, 0); return 0; diff --git a/net/lwip/src/api/tcpip.c b/net/lwip/src/api/tcpip.c index 97ae41db5b..002df90b24 100644 --- a/net/lwip/src/api/tcpip.c +++ b/net/lwip/src/api/tcpip.c @@ -297,11 +297,12 @@ tcpip_thread(void *arg) case TCPIP_MSG_TIMEOUT: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); - - if(msg->msg.tmo.msecs != 0xffffffff) - sys_timeout (msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg); - else - sys_untimeout (msg->msg.tmo.h, msg->msg.tmo.arg); + sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; + case TCPIP_MSG_UNTIMEOUT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg)); + sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg); memp_free(MEMP_TCPIP_MSG_API, msg); break; @@ -379,6 +380,14 @@ tcpip_callback_with_block(void (*f)(void *ctx), void *ctx, u8_t block) return ERR_VAL; } +/** + * call sys_timeout in tcpip_thread + * + * @param msec time in miliseconds for timeout + * @param h function to be called on timeout + * @param arg argument to pass to timeout function h + * @return ERR_MEM on memory error, ERR_OK otherwise + */ err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg) { @@ -400,6 +409,34 @@ tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg) return ERR_VAL; } +/** + * call sys_untimeout in tcpip_thread + * + * @param msec time in miliseconds for timeout + * @param h function to be called on timeout + * @param arg argument to pass to timeout function h + * @return ERR_MEM on memory error, ERR_OK otherwise + */ +err_t +tcpip_untimeout(sys_timeout_handler h, void *arg) +{ + struct tcpip_msg *msg; + + if (mbox != SYS_MBOX_NULL) { + msg = memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_UNTIMEOUT; + msg->msg.tmo.h = h; + msg->msg.tmo.arg = arg; + sys_mbox_post(mbox, msg); + return ERR_OK; + } + return ERR_VAL; +} + #if LWIP_NETCONN /** * Call the lower part of a netconn_* function @@ -518,4 +555,42 @@ tcpip_init(void (* initfunc)(void *), void *arg) sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); } +/** + * Simple callback function used with tcpip_callback to free a pbuf + * (pbuf_free has a wrong signature for tcpip_callback) + * + * @param p The pbuf (chain) to be dereferenced. + */ +static void +pbuf_free_int(void *p) +{ + struct pbuf *q = p; + pbuf_free(q); +} + +/** + * A simple wrapper function that allows you to free a pbuf from interrupt context. + * + * @param p The pbuf (chain) to be dereferenced. + * @return ERR_OK if callback could be enqueued, an err_t if not + */ +err_t +pbuf_free_callback(struct pbuf *p) +{ + return tcpip_callback_with_block(pbuf_free_int, p, 0); +} + +/** + * A simple wrapper function that allows you to free heap memory from + * interrupt context. + * + * @param m the heap memory to free + * @return ERR_OK if callback could be enqueued, an err_t if not + */ +err_t +mem_free_callback(void *m) +{ + return tcpip_callback_with_block(mem_free, m, 0); +} + #endif /* !NO_SYS */ |
