summaryrefslogtreecommitdiff
path: root/net/lwip/src/api
diff options
context:
space:
mode:
authorbernard.xiong <[email protected]>2009-09-06 11:04:38 +0000
committerbernard.xiong <[email protected]>2009-09-06 11:04:38 +0000
commitb9290bcef45a9ebc088e1f20596b7e02c7ca47f6 (patch)
treed3545a00a8b25782bf32c52f491df1188abdcfee /net/lwip/src/api
parent1ae9da2752f5ae98d029dce078c49f2a5364019c (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.c17
-rw-r--r--net/lwip/src/api/api_msg.c70
-rw-r--r--net/lwip/src/api/err.c22
-rw-r--r--net/lwip/src/api/netbuf.c4
-rw-r--r--net/lwip/src/api/netdb.c22
-rw-r--r--net/lwip/src/api/sockets.c315
-rw-r--r--net/lwip/src/api/tcpip.c85
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 */