diff --git a/CHANGELOG b/CHANGELOG index 300b3d50..8d6c2333 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,10 @@ HISTORY ++ New features: + 2014-02-20: Simon Goldschmidt (based on patch by Artem Pisarenko) + * patch #7885: modification of api modules to support FreeRTOS-MPU + (don't pass stack-pointers to other threads) + 2014-02-05: Simon Goldschmidt (patch by "xtian" and "alex_ab") * patch #6537/#7858: TCP window scaling support diff --git a/src/api/api_lib.c b/src/api/api_lib.c index adaaad43..971fe918 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -54,6 +54,12 @@ #include +#define API_MSG_VAR_REF(name) API_VAR_REF(name) +#define API_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct api_msg, name) +#define API_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name) +#define API_MSG_VAR_ALLOC_DONTFAIL(name) API_VAR_ALLOC_DONTFAIL(struct api_msg, MEMP_API_MSG, name) +#define API_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_API_MSG, name) + /** * Create a new netconn (of a specific type) that has a callback function. * The corresponding pcb is also created. @@ -68,14 +74,16 @@ struct netconn* netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback) { struct netconn *conn; - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); conn = netconn_alloc(t, callback); if (conn != NULL) { err_t err; - msg.msg.msg.n.proto = proto; - msg.msg.conn = conn; - TCPIP_APIMSG((&msg), lwip_netconn_do_newconn, err); + API_MSG_VAR_ALLOC_DONTFAIL(msg); + API_MSG_VAR_REF(msg).msg.msg.n.proto = proto; + API_MSG_VAR_REF(msg).msg.conn = conn; + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_newconn, err); + API_MSG_VAR_FREE(msg); if (err != ERR_OK) { LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL); LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed)); @@ -103,16 +111,18 @@ netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_cal err_t netconn_delete(struct netconn *conn) { - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */ if (conn == NULL) { return ERR_OK; } - msg.function = lwip_netconn_do_delconn; - msg.msg.conn = conn; - tcpip_apimsg(&msg); + API_MSG_VAR_ALLOC(msg); + API_MSG_VAR_REF(msg).function = lwip_netconn_do_delconn; + API_MSG_VAR_REF(msg).msg.conn = conn; + tcpip_apimsg(&API_MSG_VAR_REF(msg)); + API_MSG_VAR_FREE(msg); netconn_free(conn); @@ -135,18 +145,26 @@ netconn_delete(struct netconn *conn) err_t netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local) { - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); err_t err; LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;); LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;); LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;); - msg.msg.conn = conn; + API_MSG_VAR_ALLOC(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.ad.local = local; +#if LWIP_MPU_COMPATIBLE + TCPIP_APIMSG(msg, lwip_netconn_do_getaddr, err); + *addr = *ipX_2_ip(&(msg->msg.msg.ad.ipaddr)); + *port = msg->msg.msg.ad.port; +#else /* LWIP_MPU_COMPATIBLE */ msg.msg.msg.ad.ipaddr = ip_2_ipX(addr); msg.msg.msg.ad.port = port; - msg.msg.msg.ad.local = local; TCPIP_APIMSG(&msg, lwip_netconn_do_getaddr, err); +#endif /* LWIP_MPU_COMPATIBLE */ + API_MSG_VAR_FREE(msg); NETCONN_SET_SAFE_ERR(conn, err); return err; @@ -165,15 +183,22 @@ netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local) err_t netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port) { - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); err_t err; LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;); - msg.msg.conn = conn; - msg.msg.msg.bc.ipaddr = addr; - msg.msg.msg.bc.port = port; - TCPIP_APIMSG(&msg, lwip_netconn_do_bind, err); + API_MSG_VAR_ALLOC(msg); +#if LWIP_MPU_COMPATIBLE + if (addr == NULL) { + addr = IP_ADDR_ANY; + } +#endif /* LWIP_MPU_COMPATIBLE */ + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.bc.ipaddr = API_MSG_VAR_REF(addr); + API_MSG_VAR_REF(msg).msg.msg.bc.port = port; + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_bind, err); + API_MSG_VAR_FREE(msg); NETCONN_SET_SAFE_ERR(conn, err); return err; @@ -190,14 +215,20 @@ netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port) err_t netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port) { - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); err_t err; LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;); - msg.msg.conn = conn; - msg.msg.msg.bc.ipaddr = addr; - msg.msg.msg.bc.port = port; + API_MSG_VAR_ALLOC(msg); +#if LWIP_MPU_COMPATIBLE + if (addr == NULL) { + addr = IP_ADDR_ANY; + } +#endif /* LWIP_MPU_COMPATIBLE */ + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.bc.ipaddr = API_MSG_VAR_REF(addr); + API_MSG_VAR_REF(msg).msg.msg.bc.port = port; #if LWIP_TCP #if (LWIP_UDP || LWIP_RAW) if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) @@ -205,8 +236,8 @@ netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port) { /* The TCP version waits for the connect to succeed, so always needs to use message passing. */ - msg.function = lwip_netconn_do_connect; - err = tcpip_apimsg(&msg); + API_MSG_VAR_REF(msg).function = lwip_netconn_do_connect; + err = tcpip_apimsg(&API_MSG_VAR_REF(msg)); } #endif /* LWIP_TCP */ #if (LWIP_UDP || LWIP_RAW) && LWIP_TCP @@ -215,9 +246,10 @@ netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port) #if (LWIP_UDP || LWIP_RAW) { /* UDP and RAW only set flags, so we can use core-locking. */ - TCPIP_APIMSG(&msg, lwip_netconn_do_connect, err); + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_connect, err); } #endif /* (LWIP_UDP || LWIP_RAW) */ + API_MSG_VAR_FREE(msg); NETCONN_SET_SAFE_ERR(conn, err); return err; @@ -232,13 +264,15 @@ netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port) err_t netconn_disconnect(struct netconn *conn) { - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); err_t err; LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;); - msg.msg.conn = conn; - TCPIP_APIMSG(&msg, lwip_netconn_do_disconnect, err); + API_MSG_VAR_ALLOC(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_disconnect, err); + API_MSG_VAR_FREE(msg); NETCONN_SET_SAFE_ERR(conn, err); return err; @@ -256,7 +290,7 @@ err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog) { #if LWIP_TCP - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); err_t err; /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */ @@ -264,11 +298,13 @@ netconn_listen_with_backlog(struct netconn *conn, u8_t backlog) LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;); - msg.msg.conn = conn; + API_MSG_VAR_ALLOC(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; #if TCP_LISTEN_BACKLOG - msg.msg.msg.lb.backlog = backlog; + API_MSG_VAR_REF(msg).msg.msg.lb.backlog = backlog; #endif /* TCP_LISTEN_BACKLOG */ - TCPIP_APIMSG(&msg, lwip_netconn_do_listen, err); + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_listen, err); + API_MSG_VAR_FREE(msg); NETCONN_SET_SAFE_ERR(conn, err); return err; @@ -294,7 +330,7 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn) struct netconn *newconn; err_t err; #if TCP_LISTEN_BACKLOG - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); #endif /* TCP_LISTEN_BACKLOG */ LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;); @@ -327,9 +363,11 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn) } #if TCP_LISTEN_BACKLOG /* Let the stack know that we have accepted the connection. */ - msg.msg.conn = conn; + API_MSG_VAR_ALLOC_DONTFAIL(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; /* don't care for the return value of lwip_netconn_do_recv */ - TCPIP_APIMSG_NOERR(&msg, lwip_netconn_do_recv); + TCPIP_APIMSG_NOERR(&API_MSG_VAR_REF(msg), lwip_netconn_do_recv); + API_MSG_VAR_FREE(msg); #endif /* TCP_LISTEN_BACKLOG */ *new_conn = newconn; @@ -358,7 +396,7 @@ netconn_recv_data(struct netconn *conn, void **new_buf) u16_t len; err_t err; #if LWIP_TCP - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); #endif /* LWIP_TCP */ LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); @@ -393,14 +431,16 @@ netconn_recv_data(struct netconn *conn, void **new_buf) /* Let the stack know that we have taken the data. */ /* TODO: Speedup: Don't block and wait for the answer here (to prevent multiple thread-switches). */ - msg.msg.conn = conn; + API_MSG_VAR_ALLOC_DONTFAIL(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; if (buf != NULL) { - msg.msg.msg.r.len = ((struct pbuf *)buf)->tot_len; + API_MSG_VAR_REF(msg).msg.msg.r.len = ((struct pbuf *)buf)->tot_len; } else { - msg.msg.msg.r.len = 1; + API_MSG_VAR_REF(msg).msg.msg.r.len = 1; } /* don't care for the return value of lwip_netconn_do_recv */ - TCPIP_APIMSG_NOERR(&msg, lwip_netconn_do_recv); + TCPIP_APIMSG_NOERR(&API_MSG_VAR_REF(msg), lwip_netconn_do_recv); + API_MSG_VAR_FREE(msg); } /* If we are closed, we indicate that we no longer wish to use the socket */ @@ -531,14 +571,16 @@ netconn_recved(struct netconn *conn, u32_t length) #if LWIP_TCP if ((conn != NULL) && (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) && (netconn_get_noautorecved(conn))) { - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); /* Let the stack know that we have taken the data. */ /* TODO: Speedup: Don't block and wait for the answer here (to prevent multiple thread-switches). */ - msg.msg.conn = conn; - msg.msg.msg.r.len = length; + API_MSG_VAR_ALLOC_DONTFAIL(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.r.len = length; /* don't care for the return value of lwip_netconn_do_recv */ - TCPIP_APIMSG_NOERR(&msg, lwip_netconn_do_recv); + TCPIP_APIMSG_NOERR(&API_MSG_VAR_REF(msg), lwip_netconn_do_recv); + API_MSG_VAR_FREE(msg); } #else /* LWIP_TCP */ LWIP_UNUSED_ARG(conn); @@ -577,15 +619,17 @@ netconn_sendto(struct netconn *conn, struct netbuf *buf, ip_addr_t *addr, u16_t err_t netconn_send(struct netconn *conn, struct netbuf *buf) { - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); err_t err; LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;); LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len)); - msg.msg.conn = conn; - msg.msg.msg.b = buf; - TCPIP_APIMSG(&msg, lwip_netconn_do_send, err); + API_MSG_VAR_ALLOC(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.b = buf; + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_send, err); + API_MSG_VAR_FREE(msg); NETCONN_SET_SAFE_ERR(conn, err); return err; @@ -608,7 +652,7 @@ err_t netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, u8_t apiflags, size_t *bytes_written) { - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); err_t err; u8_t dontblock; @@ -624,25 +668,26 @@ netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, return ERR_VAL; } + API_MSG_VAR_ALLOC(msg); /* non-blocking write sends as much */ - msg.msg.conn = conn; - msg.msg.msg.w.dataptr = dataptr; - msg.msg.msg.w.apiflags = apiflags; - msg.msg.msg.w.len = size; + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.w.dataptr = dataptr; + API_MSG_VAR_REF(msg).msg.msg.w.apiflags = apiflags; + API_MSG_VAR_REF(msg).msg.msg.w.len = size; #if LWIP_SO_SNDTIMEO if (conn->send_timeout != 0) { /* get the time we started, which is later compared to sys_now() + conn->send_timeout */ - msg.msg.msg.w.time_started = sys_now(); + API_MSG_VAR_REF(msg).msg.msg.w.time_started = sys_now(); } else { - msg.msg.msg.w.time_started = 0; + API_MSG_VAR_REF(msg).msg.msg.w.time_started = 0; } #endif /* LWIP_SO_SNDTIMEO */ /* For locking the core: this _can_ be delayed on low memory/low send buffer, but if it is, this is done inside api_msg.c:do_write(), so we can use the non-blocking version here. */ - TCPIP_APIMSG(&msg, lwip_netconn_do_write, err); + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_write, err); if ((err == ERR_OK) && (bytes_written != NULL)) { if (dontblock #if LWIP_SO_SNDTIMEO @@ -650,12 +695,13 @@ netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, #endif /* LWIP_SO_SNDTIMEO */ ) { /* nonblocking write: maybe the data has been sent partly */ - *bytes_written = msg.msg.msg.w.len; + *bytes_written = API_MSG_VAR_REF(msg).msg.msg.w.len; } else { /* blocking call succeeded: all data has been sent if it */ *bytes_written = size; } } + API_MSG_VAR_FREE(msg); NETCONN_SET_SAFE_ERR(conn, err); return err; @@ -671,18 +717,20 @@ netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, static err_t netconn_close_shutdown(struct netconn *conn, u8_t how) { - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); err_t err; LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;); - msg.function = lwip_netconn_do_close; - msg.msg.conn = conn; + API_MSG_VAR_ALLOC(msg); + API_MSG_VAR_REF(msg).function = lwip_netconn_do_close; + API_MSG_VAR_REF(msg).msg.conn = conn; /* shutting down both ends is the same as closing */ - msg.msg.msg.sd.shut = how; + API_MSG_VAR_REF(msg).msg.msg.sd.shut = how; /* because of the LWIP_TCPIP_CORE_LOCKING implementation of lwip_netconn_do_close, don't use TCPIP_APIMSG here */ - err = tcpip_apimsg(&msg); + err = tcpip_apimsg(&API_MSG_VAR_REF(msg)); + API_MSG_VAR_FREE(msg); NETCONN_SET_SAFE_ERR(conn, err); return err; @@ -730,16 +778,26 @@ netconn_join_leave_group(struct netconn *conn, ip_addr_t *netif_addr, enum netconn_igmp join_or_leave) { - struct api_msg msg; + API_MSG_VAR_DECLARE(msg); err_t err; LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;); - msg.msg.conn = conn; - msg.msg.msg.jl.multiaddr = ip_2_ipX(multiaddr); - msg.msg.msg.jl.netif_addr = ip_2_ipX(netif_addr); - msg.msg.msg.jl.join_or_leave = join_or_leave; - TCPIP_APIMSG(&msg, lwip_netconn_do_join_leave_group, err); + API_MSG_VAR_ALLOC(msg); +#if LWIP_MPU_COMPATIBLE + if (multiaddr == NULL) { + multiaddr = IP_ADDR_ANY; + } + if (netif_addr == NULL) { + netif_addr = IP_ADDR_ANY; + } +#endif /* LWIP_MPU_COMPATIBLE */ + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.jl.multiaddr = API_MSG_VAR_REF(ip_2_ipX(multiaddr)); + API_MSG_VAR_REF(msg).msg.msg.jl.netif_addr = API_MSG_VAR_REF(ip_2_ipX(netif_addr)); + API_MSG_VAR_REF(msg).msg.msg.jl.join_or_leave = join_or_leave; + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_join_leave_group, err); + API_MSG_VAR_FREE(msg); NETCONN_SET_SAFE_ERR(conn, err); return err; @@ -760,27 +818,42 @@ netconn_join_leave_group(struct netconn *conn, err_t netconn_gethostbyname(const char *name, ip_addr_t *addr) { - struct dns_api_msg msg; - err_t err; + API_VAR_DECLARE(struct dns_api_msg, msg); +#if !LWIP_MPU_COMPATIBLE sys_sem_t sem; +#endif /* LWIP_MPU_COMPATIBLE */ + err_t err; LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;); LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;); - err = sys_sem_new(&sem, 0); - if (err != ERR_OK) { - return err; + API_VAR_ALLOC(struct dns_api_msg, MEMP_DNS_API_MSG, msg); +#if LWIP_MPU_COMPATIBLE + if (addr == NULL) { + addr = IP_ADDR_ANY; } - - msg.name = name; - msg.addr = addr; +#else msg.err = &err; msg.sem = &sem; + API_VAR_REF(msg).addr = API_VAR_REF(addr); +#endif /* LWIP_MPU_COMPATIBLE */ + err = sys_sem_new(API_EXPR_REF(API_VAR_REF(msg).sem), 0); + if (err != ERR_OK) { + API_VAR_FREE(MEMP_DNS_API_MSG, msg); + return err; + } + API_VAR_REF(msg).name = name; - tcpip_callback(lwip_netconn_do_gethostbyname, &msg); - sys_sem_wait(&sem); - sys_sem_free(&sem); + tcpip_callback(lwip_netconn_do_gethostbyname, &API_VAR_REF(msg)); + sys_sem_wait(API_EXPR_REF(API_VAR_REF(msg).sem)); + sys_sem_free(API_EXPR_REF(API_VAR_REF(msg).sem)); +#if LWIP_MPU_COMPATIBLE + *addr = msg->addr; + err = msg->err; +#endif /* LWIP_MPU_COMPATIBLE */ + + API_VAR_FREE(MEMP_DNS_API_MSG, msg); return err; } #endif /* LWIP_DNS*/ diff --git a/src/api/api_msg.c b/src/api/api_msg.c index 02973389..7f7138ed 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -907,17 +907,17 @@ lwip_netconn_do_bind(struct api_msg_msg *msg) switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: - msg->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr); + msg->err = raw_bind(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: - msg->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); + msg->err = udp_bind(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: - msg->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port); + msg->err = tcp_bind(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); break; #endif /* LWIP_TCP */ default: @@ -997,12 +997,12 @@ lwip_netconn_do_connect(struct api_msg_msg *msg) switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: - msg->err = raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr); + msg->err = raw_connect(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: - msg->err = udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); + msg->err = udp_connect(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); break; #endif /* LWIP_UDP */ #if LWIP_TCP @@ -1012,7 +1012,7 @@ lwip_netconn_do_connect(struct api_msg_msg *msg) msg->err = ERR_ISCONN; } else { setup_tcp(msg->conn); - msg->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, + msg->err = tcp_connect(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port, lwip_netconn_do_connected); if (msg->err == ERR_OK) { u8_t non_blocking = netconn_is_nonblocking(msg->conn); @@ -1422,10 +1422,10 @@ lwip_netconn_do_getaddr(struct api_msg_msg *msg) { if (msg->conn->pcb.ip != NULL) { if (msg->msg.ad.local) { - ipX_addr_copy(PCB_ISIPV6(msg->conn->pcb.ip), *(msg->msg.ad.ipaddr), + ipX_addr_copy(PCB_ISIPV6(msg->conn->pcb.ip), API_EXPR_DEREF(msg->msg.ad.ipaddr), msg->conn->pcb.ip->local_ip); } else { - ipX_addr_copy(PCB_ISIPV6(msg->conn->pcb.ip), *(msg->msg.ad.ipaddr), + ipX_addr_copy(PCB_ISIPV6(msg->conn->pcb.ip), API_EXPR_DEREF(msg->msg.ad.ipaddr), msg->conn->pcb.ip->remote_ip); } msg->err = ERR_OK; @@ -1433,7 +1433,7 @@ lwip_netconn_do_getaddr(struct api_msg_msg *msg) #if LWIP_RAW case NETCONN_RAW: if (msg->msg.ad.local) { - *(msg->msg.ad.port) = msg->conn->pcb.raw->protocol; + API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.raw->protocol; } else { /* return an error as connecting is only a helper for upper layers */ msg->err = ERR_CONN; @@ -1443,19 +1443,19 @@ lwip_netconn_do_getaddr(struct api_msg_msg *msg) #if LWIP_UDP case NETCONN_UDP: if (msg->msg.ad.local) { - *(msg->msg.ad.port) = msg->conn->pcb.udp->local_port; + API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->local_port; } else { if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) { msg->err = ERR_CONN; } else { - *(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port; + API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port; } } break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: - *(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port); + API_EXPR_DEREF(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port); break; #endif /* LWIP_TCP */ default: @@ -1528,11 +1528,11 @@ lwip_netconn_do_join_leave_group(struct api_msg_msg *msg) #if LWIP_IPV6 && LWIP_IPV6_MLD if (PCB_ISIPV6(msg->conn->pcb.udp)) { if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { - msg->err = mld6_joingroup(ipX_2_ip6(msg->msg.jl.netif_addr), - ipX_2_ip6(msg->msg.jl.multiaddr)); + msg->err = mld6_joingroup(ipX_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), + ipX_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); } else { - msg->err = mld6_leavegroup(ipX_2_ip6(msg->msg.jl.netif_addr), - ipX_2_ip6(msg->msg.jl.multiaddr)); + msg->err = mld6_leavegroup(ipX_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), + ipX_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); } } else @@ -1540,11 +1540,11 @@ lwip_netconn_do_join_leave_group(struct api_msg_msg *msg) { #if LWIP_IGMP if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { - msg->err = igmp_joingroup(ipX_2_ip(msg->msg.jl.netif_addr), - ipX_2_ip(msg->msg.jl.multiaddr)); + msg->err = igmp_joingroup(ipX_2_ip(API_EXPR_REF(msg->msg.jl.netif_addr)), + ipX_2_ip(API_EXPR_REF(msg->msg.jl.multiaddr))); } else { - msg->err = igmp_leavegroup(ipX_2_ip(msg->msg.jl.netif_addr), - ipX_2_ip(msg->msg.jl.multiaddr)); + msg->err = igmp_leavegroup(ipX_2_ip(API_EXPR_REF(msg->msg.jl.netif_addr)), + ipX_2_ip(API_EXPR_REF(msg->msg.jl.multiaddr))); } #endif /* LWIP_IGMP */ } @@ -1578,14 +1578,14 @@ lwip_netconn_do_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) if (ipaddr == NULL) { /* timeout or memory error */ - *msg->err = ERR_VAL; + API_EXPR_DEREF(msg->err) = ERR_VAL; } else { /* address was resolved */ - *msg->err = ERR_OK; - *msg->addr = *ipaddr; + API_EXPR_DEREF(msg->err) = ERR_OK; + API_EXPR_DEREF(msg->addr) = *ipaddr; } /* wake up the application task waiting in netconn_gethostbyname */ - sys_sem_signal(msg->sem); + sys_sem_signal(API_EXPR_REF(msg->sem)); } /** @@ -1599,11 +1599,11 @@ lwip_netconn_do_gethostbyname(void *arg) { struct dns_api_msg *msg = (struct dns_api_msg*)arg; - *msg->err = dns_gethostbyname(msg->name, msg->addr, lwip_netconn_do_dns_found, msg); - if (*msg->err != ERR_INPROGRESS) { + API_EXPR_DEREF(msg->err) = dns_gethostbyname(msg->name, API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg); + if (API_EXPR_DEREF(msg->err) != ERR_INPROGRESS) { /* on error or immediate success, wake up the application * task waiting in netconn_gethostbyname */ - sys_sem_signal(msg->sem); + sys_sem_signal(API_EXPR_REF(msg->sem)); } } #endif /* LWIP_DNS */ diff --git a/src/api/netifapi.c b/src/api/netifapi.c index 81403f82..715d515e 100644 --- a/src/api/netifapi.c +++ b/src/api/netifapi.c @@ -37,6 +37,12 @@ #include "lwip/netifapi.h" #include "lwip/tcpip.h" +#include "lwip/memp.h" + +#define NETIFAPI_VAR_REF(name) API_VAR_REF(name) +#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name) +#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name) +#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name) /** * Call netif_add() inside the tcpip_thread context. @@ -45,9 +51,9 @@ static void netifapi_do_netif_add(struct netifapi_msg_msg *msg) { if (!netif_add( msg->netif, - msg->msg.add.ipaddr, - msg->msg.add.netmask, - msg->msg.add.gw, + API_EXPR_REF(msg->msg.add.ipaddr), + API_EXPR_REF(msg->msg.add.netmask), + API_EXPR_REF(msg->msg.add.gw), msg->msg.add.state, msg->msg.add.init, msg->msg.add.input)) { @@ -65,9 +71,9 @@ static void netifapi_do_netif_set_addr(struct netifapi_msg_msg *msg) { netif_set_addr( msg->netif, - msg->msg.add.ipaddr, - msg->msg.add.netmask, - msg->msg.add.gw); + API_EXPR_REF(msg->msg.add.ipaddr), + API_EXPR_REF(msg->msg.add.netmask), + API_EXPR_REF(msg->msg.add.gw)); msg->err = ERR_OK; TCPIP_NETIFAPI_ACK(msg); } @@ -103,17 +109,33 @@ netifapi_netif_add(struct netif *netif, netif_init_fn init, netif_input_fn input) { - struct netifapi_msg msg; - msg.function = netifapi_do_netif_add; - msg.msg.netif = netif; - msg.msg.msg.add.ipaddr = ipaddr; - msg.msg.msg.add.netmask = netmask; - msg.msg.msg.add.gw = gw; - msg.msg.msg.add.state = state; - msg.msg.msg.add.init = init; - msg.msg.msg.add.input = input; - TCPIP_NETIFAPI(&msg); - return msg.msg.err; + err_t err; + NETIFAPI_VAR_DECLARE(msg); + NETIFAPI_VAR_ALLOC(msg); +#if LWIP_MPU_COMPATIBLE + if (ipaddr == NULL) { + ipaddr = IP_ADDR_ANY; + } + if (netmask == NULL) { + netmask = IP_ADDR_ANY; + } + if (gw == NULL) { + gw = IP_ADDR_ANY; + } +#endif /* LWIP_MPU_COMPATIBLE */ + NETIFAPI_VAR_REF(msg).function = netifapi_do_netif_add; + NETIFAPI_VAR_REF(msg).msg.netif = netif; + NETIFAPI_VAR_REF(msg).msg.msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr); + NETIFAPI_VAR_REF(msg).msg.msg.add.netmask = NETIFAPI_VAR_REF(netmask); + NETIFAPI_VAR_REF(msg).msg.msg.add.gw = NETIFAPI_VAR_REF(gw); + NETIFAPI_VAR_REF(msg).msg.msg.add.state = state; + NETIFAPI_VAR_REF(msg).msg.msg.add.init = init; + NETIFAPI_VAR_REF(msg).msg.msg.add.input = input; + TCPIP_NETIFAPI(&API_VAR_REF(msg)); + + err = NETIFAPI_VAR_REF(msg).msg.err; + NETIFAPI_VAR_FREE(msg); + return err; } /** @@ -128,14 +150,30 @@ netifapi_netif_set_addr(struct netif *netif, ip_addr_t *netmask, ip_addr_t *gw) { - struct netifapi_msg msg; - msg.function = netifapi_do_netif_set_addr; - msg.msg.netif = netif; - msg.msg.msg.add.ipaddr = ipaddr; - msg.msg.msg.add.netmask = netmask; - msg.msg.msg.add.gw = gw; - TCPIP_NETIFAPI(&msg); - return msg.msg.err; + err_t err; + NETIFAPI_VAR_DECLARE(msg); + NETIFAPI_VAR_ALLOC(msg); +#if LWIP_MPU_COMPATIBLE + if (ipaddr == NULL) { + ipaddr = IP_ADDR_ANY; + } + if (netmask == NULL) { + netmask = IP_ADDR_ANY; + } + if (gw == NULL) { + gw = IP_ADDR_ANY; + } +#endif /* LWIP_MPU_COMPATIBLE */ + NETIFAPI_VAR_REF(msg).function = netifapi_do_netif_set_addr; + NETIFAPI_VAR_REF(msg).msg.netif = netif; + NETIFAPI_VAR_REF(msg).msg.msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr); + NETIFAPI_VAR_REF(msg).msg.msg.add.netmask = NETIFAPI_VAR_REF(netmask); + NETIFAPI_VAR_REF(msg).msg.msg.add.gw = NETIFAPI_VAR_REF(gw); + TCPIP_NETIFAPI(&API_VAR_REF(msg)); + + err = NETIFAPI_VAR_REF(msg).msg.err; + NETIFAPI_VAR_FREE(msg); + return err; } /** @@ -148,13 +186,19 @@ err_t netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, netifapi_errt_fn errtfunc) { - struct netifapi_msg msg; - msg.function = netifapi_do_netif_common; - msg.msg.netif = netif; - msg.msg.msg.common.voidfunc = voidfunc; - msg.msg.msg.common.errtfunc = errtfunc; - TCPIP_NETIFAPI(&msg); - return msg.msg.err; + err_t err; + NETIFAPI_VAR_DECLARE(msg); + NETIFAPI_VAR_ALLOC(msg); + + NETIFAPI_VAR_REF(msg).function = netifapi_do_netif_common; + NETIFAPI_VAR_REF(msg).msg.netif = netif; + NETIFAPI_VAR_REF(msg).msg.msg.common.voidfunc = voidfunc; + NETIFAPI_VAR_REF(msg).msg.msg.common.errtfunc = errtfunc; + TCPIP_NETIFAPI(&API_VAR_REF(msg)); + + err = NETIFAPI_VAR_REF(msg).msg.err; + NETIFAPI_VAR_FREE(msg); + return err; } #endif /* LWIP_NETIF_API */ diff --git a/src/api/sockets.c b/src/api/sockets.c index 66036712..22905539 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -51,6 +51,7 @@ #include "lwip/raw.h" #include "lwip/udp.h" #include "lwip/tcpip.h" +#include "lwip/memp.h" #include "lwip/pbuf.h" #if LWIP_CHECKSUM_ON_COPY #include "lwip/inet_chksum.h" @@ -117,6 +118,20 @@ #define IS_SOCK_ADDR_ALIGNED(name) ((((mem_ptr_t)(name)) % 4) == 0) +#define LWIP_SETGETSOCKOPT_DATA_VAR_REF(name) API_VAR_REF(name) +#define LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_setgetsockopt_data, name) +#define LWIP_SETGETSOCKOPT_DATA_VAR_FREE(name) API_VAR_FREE(MEMP_SOCKET_SETGETSOCKOPT_DATA, name) +#if LWIP_MPU_COMPATIBLE +#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) do { \ + name = (struct lwip_setgetsockopt_data *)memp_malloc(MEMP_SOCKET_SETGETSOCKOPT_DATA); \ + if (name == NULL) { \ + sock_set_errno(sock, ERR_MEM); \ + return -1; \ + } }while(0) +#else /* LWIP_MPU_COMPATIBLE */ +#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) +#endif /* LWIP_MPU_COMPATIBLE */ + #define NUM_SOCKETS MEMP_NUM_NETCONN @@ -160,28 +175,6 @@ struct lwip_select_cb { sys_sem_t sem; }; -/** This struct is used to pass data to the set/getsockopt_internal - * functions running in tcpip_thread context (only a void* is allowed) */ -struct lwip_setgetsockopt_data { - /** socket struct for which to change options */ - struct lwip_sock *sock; -#ifdef LWIP_DEBUG - /** socket index for which to change options */ - int s; -#endif /* LWIP_DEBUG */ - /** level of the option to process */ - int level; - /** name of the option to process */ - int optname; - /** set: value to set the option to - * get: value of the option is stored here */ - void *optval; - /** size of *optval */ - socklen_t *optlen; - /** if an error occures, it is temporarily stored here */ - err_t err; -}; - /** A struct sockaddr replacement that has the same alignment as sockaddr_in/ * sockaddr_in6 if instantiated. */ @@ -1526,7 +1519,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) { err_t err = ERR_OK; struct lwip_sock *sock = get_socket(s); - struct lwip_setgetsockopt_data data; + LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); if (!sock) { return -1; @@ -1724,19 +1717,21 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) } /* Now do the actual option processing */ - data.sock = sock; + LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).sock = sock; #ifdef LWIP_DEBUG - data.s = s; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; #endif /* LWIP_DEBUG */ - data.level = level; - data.optname = optname; - data.optval = optval; - data.optlen = optlen; - data.err = err; - tcpip_callback(lwip_getsockopt_internal, &data); + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval = optval; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = optlen; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = err; + tcpip_callback(lwip_getsockopt_internal, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); sys_arch_sem_wait(&sock->conn->op_completed, 0); /* maybe lwip_getsockopt_internal has changed err */ - err = data.err; + err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; + LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); sock_set_errno(sock, err); return err ? -1 : 0; @@ -1972,7 +1967,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt { struct lwip_sock *sock = get_socket(s); err_t err = ERR_OK; - struct lwip_setgetsockopt_data data; + LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); if (!sock) { return -1; @@ -2181,19 +2176,21 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt /* Now do the actual option processing */ - data.sock = sock; + LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).sock = sock; #ifdef LWIP_DEBUG - data.s = s; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; #endif /* LWIP_DEBUG */ - data.level = level; - data.optname = optname; - data.optval = (void*)optval; - data.optlen = &optlen; - data.err = err; - tcpip_callback(lwip_setsockopt_internal, &data); + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval = (void*)optval; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = &optlen; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = err; + tcpip_callback(lwip_setsockopt_internal, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); sys_arch_sem_wait(&sock->conn->op_completed, 0); /* maybe lwip_setsockopt_internal has changed err */ - err = data.err; + err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; + LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); sock_set_errno(sock, err); return err ? -1 : 0; diff --git a/src/api/tcpip.c b/src/api/tcpip.c index 2c0032c2..31e7c924 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -50,6 +50,11 @@ #include "netif/etharp.h" #include "netif/ppp_oe.h" +#define TCPIP_MSG_VAR_REF(name) API_VAR_REF(name) +#define TCPIP_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct tcpip_msg, name) +#define TCPIP_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name) +#define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name) + /* global variables */ static tcpip_init_done_fn tcpip_init_done; static void *tcpip_init_done_arg; @@ -311,17 +316,19 @@ tcpip_untimeout(sys_timeout_handler h, void *arg) err_t tcpip_apimsg(struct api_msg *apimsg) { - struct tcpip_msg msg; + TCPIP_MSG_VAR_DECLARE(msg); #ifdef LWIP_DEBUG /* catch functions that don't set err */ apimsg->msg.err = ERR_VAL; #endif if (sys_mbox_valid(&mbox)) { - msg.type = TCPIP_MSG_API; - msg.msg.apimsg = apimsg; - sys_mbox_post(&mbox, &msg); + TCPIP_MSG_VAR_ALLOC(msg); + TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API; + TCPIP_MSG_VAR_REF(msg).msg.apimsg = apimsg; + sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg)); sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0); + TCPIP_MSG_VAR_FREE(msg); return apimsg->msg.err; } return ERR_VAL; @@ -341,20 +348,24 @@ tcpip_apimsg(struct api_msg *apimsg) err_t tcpip_netifapi(struct netifapi_msg* netifapimsg) { - struct tcpip_msg msg; - + TCPIP_MSG_VAR_DECLARE(msg); + if (sys_mbox_valid(&mbox)) { - err_t err = sys_sem_new(&netifapimsg->msg.sem, 0); + err_t err; + TCPIP_MSG_VAR_ALLOC(msg); + + err = sys_sem_new(&netifapimsg->msg.sem, 0); if (err != ERR_OK) { netifapimsg->msg.err = err; return err; } - msg.type = TCPIP_MSG_NETIFAPI; - msg.msg.netifapimsg = netifapimsg; - sys_mbox_post(&mbox, &msg); + TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_NETIFAPI; + TCPIP_MSG_VAR_REF(msg).msg.netifapimsg = netifapimsg; + sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg)); sys_sem_wait(&netifapimsg->msg.sem); sys_sem_free(&netifapimsg->msg.sem); + TCPIP_MSG_VAR_FREE(msg); return netifapimsg->msg.err; } return ERR_VAL; diff --git a/src/core/init.c b/src/core/init.c index 52d7baa0..3095bd38 100644 --- a/src/core/init.c +++ b/src/core/init.c @@ -232,9 +232,6 @@ #ifdef MEMP_NUM_TCPIP_MSG #error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h." #endif -#ifdef MEMP_NUM_API_MSG - #error "MEMP_NUM_API_MSG option is deprecated. Remove it from your lwipopts.h." -#endif #ifdef TCP_REXMIT_DEBUG #error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h." #endif diff --git a/src/core/memp.c b/src/core/memp.c index cc967981..992b2307 100644 --- a/src/core/memp.c +++ b/src/core/memp.c @@ -48,6 +48,7 @@ #include "lwip/igmp.h" #include "lwip/api.h" #include "lwip/api_msg.h" +#include "lwip/sockets.h" #include "lwip/tcpip.h" #include "lwip/sys.h" #include "lwip/timers.h" diff --git a/src/include/lwip/api_msg.h b/src/include/lwip/api_msg.h index 8268036a..95614b7a 100644 --- a/src/include/lwip/api_msg.h +++ b/src/include/lwip/api_msg.h @@ -48,6 +48,12 @@ extern "C" { #endif +#if LWIP_MPU_COMPATIBLE +#define API_MSG_M_DEF(m) m +#else /* LWIP_MPU_COMPATIBLE */ +#define API_MSG_M_DEF(m) *m +#endif /* LWIP_MPU_COMPATIBLE */ + /* For the netconn API, these values are use as a bitmask! */ #define NETCONN_SHUT_RD 1 #define NETCONN_SHUT_WR 2 @@ -75,13 +81,13 @@ struct api_msg_msg { } n; /** used for lwip_netconn_do_bind and lwip_netconn_do_connect */ struct { - ip_addr_t *ipaddr; + ip_addr_t API_MSG_M_DEF(ipaddr); u16_t port; } bc; /** used for lwip_netconn_do_getaddr */ struct { - ipX_addr_t *ipaddr; - u16_t *port; + ipX_addr_t API_MSG_M_DEF(ipaddr); + u16_t API_MSG_M_DEF(port); u8_t local; } ad; /** used for lwip_netconn_do_write */ @@ -104,8 +110,8 @@ struct api_msg_msg { #if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) /** used for lwip_netconn_do_join_leave_group */ struct { - ipX_addr_t *multiaddr; - ipX_addr_t *netif_addr; + ipX_addr_t API_MSG_M_DEF(multiaddr); + ipX_addr_t API_MSG_M_DEF(netif_addr); enum netconn_igmp join_or_leave; } jl; #endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ @@ -136,12 +142,12 @@ struct dns_api_msg { /** Hostname to query or dotted IP address string */ const char *name; /** Rhe resolved address is stored here */ - ip_addr_t *addr; + ip_addr_t API_MSG_M_DEF(addr); /** This semaphore is posted when the name is resolved, the application thread should wait on it. */ - sys_sem_t *sem; + sys_sem_t API_MSG_M_DEF(sem); /** Errors are given back here */ - err_t *err; + err_t API_MSG_M_DEF(err); }; #endif /* LWIP_DNS */ diff --git a/src/include/lwip/memp_std.h b/src/include/lwip/memp_std.h index 8e1c99c4..18afe7c6 100644 --- a/src/include/lwip/memp_std.h +++ b/src/include/lwip/memp_std.h @@ -58,6 +58,18 @@ LWIP_MEMPOOL(NETCONN, MEMP_NUM_NETCONN, sizeof(struct netconn), #if NO_SYS==0 LWIP_MEMPOOL(TCPIP_MSG_API, MEMP_NUM_TCPIP_MSG_API, sizeof(struct tcpip_msg), "TCPIP_MSG_API") +#if LWIP_MPU_COMPATIBLE +LWIP_MEMPOOL(API_MSG, MEMP_NUM_API_MSG, sizeof(struct api_msg), "API_MSG") +#if LWIP_DNS +LWIP_MEMPOOL(DNS_API_MSG, MEMP_NUM_DNS_API_MSG, sizeof(struct dns_api_msg), "DNS_API_MSG") +#endif +#if LWIP_SOCKET +LWIP_MEMPOOL(SOCKET_SETGETSOCKOPT_DATA, MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA, sizeof(struct lwip_setgetsockopt_data), "SOCKET_SETGETSOCKOPT_DATA") +#endif +#if LWIP_NETIF_API +LWIP_MEMPOOL(NETIFAPI_MSG, MEMP_NUM_NETIFAPI_MSG, sizeof(struct netifapi_msg), "NETIFAPI_MSG") +#endif +#endif /* LWIP_MPU_COMPATIBLE */ #if !LWIP_TCPIP_CORE_LOCKING_INPUT LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg), "TCPIP_MSG_INPKT") #endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ diff --git a/src/include/lwip/netifapi.h b/src/include/lwip/netifapi.h index 648151b6..37a6743f 100644 --- a/src/include/lwip/netifapi.h +++ b/src/include/lwip/netifapi.h @@ -41,6 +41,12 @@ extern "C" { #endif +#if LWIP_MPU_COMPATIBLE +#define NETIFAPI_IPADDR_DEF(m) m +#else /* LWIP_MPU_COMPATIBLE */ +#define NETIFAPI_IPADDR_DEF(m) *m +#endif /* LWIP_MPU_COMPATIBLE */ + typedef void (*netifapi_void_fn)(struct netif *netif); typedef err_t (*netifapi_errt_fn)(struct netif *netif); @@ -52,9 +58,9 @@ struct netifapi_msg_msg { struct netif *netif; union { struct { - ip_addr_t *ipaddr; - ip_addr_t *netmask; - ip_addr_t *gw; + ip_addr_t NETIFAPI_IPADDR_DEF(ipaddr); + ip_addr_t NETIFAPI_IPADDR_DEF(netmask); + ip_addr_t NETIFAPI_IPADDR_DEF(gw); void *state; netif_init_fn init; netif_input_fn input; diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 82946d0f..2becda85 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -92,6 +92,16 @@ #define SMEMCPY(dst,src,len) memcpy(dst,src,len) #endif +/** + * LWIP_MPU_COMPATIBLE: enables special memory management mechanism + * which makes lwip able to work on MPU (Memory Protection Unit) system + * by not passing stack-pointers to other threads + * (this decreases performance) + */ +#ifndef LWIP_MPU_COMPATIBLE +#define LWIP_MPU_COMPATIBLE 0 +#endif + /* ------------------------------------ ---------- Memory options ---------- @@ -414,6 +424,33 @@ #define PBUF_POOL_SIZE 16 #endif +/** MEMP_NUM_API_MSG: the number of concurrently active calls to various + * socket, netconn, and tcpip functions + */ +#ifndef MEMP_NUM_API_MSG +#define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API +#endif + +/** MEMP_NUM_DNS_API_MSG: the number of concurrently active calls to netconn_gethostbyname + */ +#ifndef MEMP_NUM_DNS_API_MSG +#define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API +#endif + +/** MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA: the number of concurrently active calls + * to getsockopt/setsockopt + */ +#ifndef MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA +#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API +#endif + +/** MEMP_NUM_NETIFAPI_MSG: the number of concurrently active calls to the + * netifapi functions + */ +#ifndef MEMP_NUM_NETIFAPI_MSG +#define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API +#endif + /* --------------------------------- ---------- ARP options ---------- diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h index 74cd252c..ba4ca7b6 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h @@ -41,6 +41,7 @@ #include /* for size_t */ #include "lwip/ip_addr.h" +#include "lwip/err.h" #include "lwip/inet.h" #include "lwip/inet6.h" @@ -105,6 +106,30 @@ struct sockaddr_storage { typedef u32_t socklen_t; #endif +struct lwip_sock; + +/** This struct is used to pass data to the set/getsockopt_internal + * functions running in tcpip_thread context (only a void* is allowed) */ +struct lwip_setgetsockopt_data { + /** socket struct for which to change options */ + struct lwip_sock *sock; +#ifdef LWIP_DEBUG + /** socket index for which to change options */ + int s; +#endif /* LWIP_DEBUG */ + /** level of the option to process */ + int level; + /** name of the option to process */ + int optname; + /** set: value to set the option to + * get: value of the option is stored here */ + void *optval; + /** size of *optval */ + socklen_t *optlen; + /** if an error occures, it is temporarily stored here */ + err_t err; +}; + /* Socket protocol types (TCP/UDP/RAW) */ #define SOCK_STREAM 1 #define SOCK_DGRAM 2 diff --git a/src/include/lwip/tcpip.h b/src/include/lwip/tcpip.h index 04567f2c..5b71cf1b 100644 --- a/src/include/lwip/tcpip.h +++ b/src/include/lwip/tcpip.h @@ -87,6 +87,35 @@ extern sys_mutex_t lock_tcpip_core; #define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(&m->sem) #endif /* LWIP_TCPIP_CORE_LOCKING */ + +#if LWIP_MPU_COMPATIBLE +#define API_VAR_REF(name) (*(name)) +#define API_VAR_DECLARE(type, name) type * name +#define API_VAR_ALLOC(type, pool, name) do { \ + name = (type *)memp_malloc(pool); \ + if (name == NULL) { \ + return ERR_MEM; \ + } \ + } while(0) +#define API_VAR_ALLOC_DONTFAIL(type, pool, name) do { \ + name = (type *)memp_malloc(pool); \ + LWIP_ASSERT("pool empty", name != NULL); \ + } while(0) +#define API_VAR_FREE(pool, name) memp_free(pool, name) +#define API_EXPR_REF(expr) &(expr) +#define API_EXPR_DEREF(expr) expr +#else /* LWIP_MPU_COMPATIBLE */ +#define API_VAR_REF(name) name +#define API_VAR_DECLARE(type, name) type name +#define API_VAR_ALLOC(type, pool, name) +#define API_VAR_ALLOC_DONTFAIL(type, pool, name) +#define API_VAR_FREE(pool, name) +#define API_EXPR_REF(expr) expr +#define API_EXPR_DEREF(expr) *(expr) +#endif /* LWIP_MPU_COMPATIBLE */ + + + /** Function prototype for the init_done function passed to tcpip_init */ typedef void (*tcpip_init_done_fn)(void *arg); /** Function prototype for functions passed to tcpip_callback() */