From af1978fa4e44ff4f8ec55fe81887723a09fa5f71 Mon Sep 17 00:00:00 2001 From: Dirk Ziegelmeier Date: Mon, 7 Mar 2016 19:57:51 +0100 Subject: [PATCH] Implement generic API message handling Add generic tcpip_send_api_msg function Let netif API and netconn API use it Decouple tcpip.c and tcpip_priv.h from netif API --- src/api/api_msg.c | 48 +++++++++---- src/api/netifapi.c | 63 ++++++++++++++++- src/api/tcpip.c | 108 +++++++++-------------------- src/include/lwip/netifapi.h | 2 +- src/include/lwip/priv/api_msg.h | 28 ++++---- src/include/lwip/priv/tcpip_priv.h | 29 ++------ 6 files changed, 150 insertions(+), 128 deletions(-) diff --git a/src/api/api_msg.c b/src/api/api_msg.c index 80f4f75c..0bf6a800 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -571,8 +571,10 @@ pcb_new(struct api_msg_msg *msg) * @param msg the api_msg_msg describing the connection type */ void -lwip_netconn_do_newconn(struct api_msg_msg *msg) +lwip_netconn_do_newconn(void *m) { + struct api_msg_msg *msg = (struct api_msg_msg*)m; + msg->err = ERR_OK; if (msg->conn->pcb.tcp == NULL) { pcb_new(msg); @@ -973,8 +975,10 @@ lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM) * @param msg the api_msg_msg pointing to the connection */ void -lwip_netconn_do_delconn(struct api_msg_msg *msg) +lwip_netconn_do_delconn(void *m) { + struct api_msg_msg *msg = (struct api_msg_msg*)m; + enum netconn_state state = msg->conn->state; LWIP_ASSERT("netconn state error", /* this only happens for TCP netconns */ (state == NETCONN_NONE) || (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP)); @@ -1073,8 +1077,10 @@ lwip_netconn_do_delconn(struct api_msg_msg *msg) * the IP address and port to bind to */ void -lwip_netconn_do_bind(struct api_msg_msg *msg) +lwip_netconn_do_bind(void *m) { + struct api_msg_msg *msg = (struct api_msg_msg*)m; + if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { @@ -1179,8 +1185,10 @@ lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) * the IP address and port to connect to */ void -lwip_netconn_do_connect(struct api_msg_msg *msg) +lwip_netconn_do_connect(void *m) { + struct api_msg_msg *msg = (struct api_msg_msg*)m; + if (msg->conn->pcb.tcp == NULL) { /* This may happen when calling netconn_connect() a second time */ msg->err = ERR_CLSD; @@ -1248,8 +1256,10 @@ lwip_netconn_do_connect(struct api_msg_msg *msg) * @param msg the api_msg_msg pointing to the connection to disconnect */ void -lwip_netconn_do_disconnect(struct api_msg_msg *msg) +lwip_netconn_do_disconnect(void *m) { + struct api_msg_msg *msg = (struct api_msg_msg*)m; + #if LWIP_UDP if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { udp_disconnect(msg->conn->pcb.udp); @@ -1270,8 +1280,10 @@ lwip_netconn_do_disconnect(struct api_msg_msg *msg) * @param msg the api_msg_msg pointing to the connection */ void -lwip_netconn_do_listen(struct api_msg_msg *msg) +lwip_netconn_do_listen(void *m) { + struct api_msg_msg *msg = (struct api_msg_msg*)m; + if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { @@ -1351,8 +1363,10 @@ lwip_netconn_do_listen(struct api_msg_msg *msg) * @param msg the api_msg_msg pointing to the connection */ void -lwip_netconn_do_send(struct api_msg_msg *msg) +lwip_netconn_do_send(void *m) { + struct api_msg_msg *msg = (struct api_msg_msg*)m; + if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { @@ -1404,8 +1418,10 @@ lwip_netconn_do_send(struct api_msg_msg *msg) * @param msg the api_msg_msg pointing to the connection */ void -lwip_netconn_do_recv(struct api_msg_msg *msg) +lwip_netconn_do_recv(void *m) { + struct api_msg_msg *msg = (struct api_msg_msg*)m; + msg->err = ERR_OK; if (msg->conn->pcb.tcp != NULL) { if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { @@ -1590,8 +1606,10 @@ err_mem: * @param msg the api_msg_msg pointing to the connection */ void -lwip_netconn_do_write(struct api_msg_msg *msg) +lwip_netconn_do_write(void *m) { + struct api_msg_msg *msg = (struct api_msg_msg*)m; + if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { @@ -1644,8 +1662,10 @@ lwip_netconn_do_write(struct api_msg_msg *msg) * @param msg the api_msg_msg pointing to the connection */ void -lwip_netconn_do_getaddr(struct api_msg_msg *msg) +lwip_netconn_do_getaddr(void *m) { + struct api_msg_msg *msg = (struct api_msg_msg*)m; + if (msg->conn->pcb.ip != NULL) { if (msg->msg.ad.local) { ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), @@ -1708,8 +1728,10 @@ lwip_netconn_do_getaddr(struct api_msg_msg *msg) * @param msg the api_msg_msg pointing to the connection */ void -lwip_netconn_do_close(struct api_msg_msg *msg) +lwip_netconn_do_close(void *m) { + struct api_msg_msg *msg = (struct api_msg_msg*)m; + #if LWIP_TCP enum netconn_state state = msg->conn->state; /* First check if this is a TCP netconn and if it is in a correct state @@ -1782,8 +1804,10 @@ lwip_netconn_do_close(struct api_msg_msg *msg) * @param msg the api_msg_msg pointing to the connection */ void -lwip_netconn_do_join_leave_group(struct api_msg_msg *msg) +lwip_netconn_do_join_leave_group(void *m) { + struct api_msg_msg *msg = (struct api_msg_msg*)m; + if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { diff --git a/src/api/netifapi.c b/src/api/netifapi.c index ce0f6f0d..3f6b88ca 100644 --- a/src/api/netifapi.c +++ b/src/api/netifapi.c @@ -44,12 +44,65 @@ #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) +#if !LWIP_TCPIP_CORE_LOCKING +#define TCPIP_NETIFAPI(m) tcpip_netifapi(m) +#define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(&m->sem) + +/** + * Much like tcpip_apimsg, but calls the lower part of a netifapi_* + * function. + * + * @param netifapimsg a struct containing the function to call and its parameters + * @return error code given back by the function that was called + */ +static err_t +tcpip_netifapi(struct netifapi_msg* netifapimsg) +{ + err_t err; + + err = sys_sem_new(&netifapimsg->msg.sem, 0); + if (err != ERR_OK) { + netifapimsg->msg.err = err; + return err; + } + + if(tcpip_send_api_msg(netifapimsg->function, &netifapimsg->msg, &netifapimsg->msg.sem) == ERR_OK) + { + sys_sem_free(&netifapimsg->msg.sem); + return netifapimsg->msg.err; + } + return ERR_VAL; +} +#else /* !LWIP_TCPIP_CORE_LOCKING */ +#define TCPIP_NETIFAPI(m) tcpip_netifapi_lock(m) +#define TCPIP_NETIFAPI_ACK(m) + +/** + * Call the lower part of a netifapi_* function + * This function has exclusive access to lwIP core code by locking it + * before the function is called. + * + * @param netifapimsg a struct containing the function to call and its parameters + * @return ERR_OK (only for compatibility fo tcpip_netifapi()) + */ +static err_t +tcpip_netifapi_lock(struct netifapi_msg* netifapimsg) +{ + LOCK_TCPIP_CORE(); + netifapimsg->function(&(netifapimsg->msg)); + UNLOCK_TCPIP_CORE(); + return netifapimsg->msg.err; +} +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + /** * Call netif_add() inside the tcpip_thread context. */ static void -netifapi_do_netif_add(struct netifapi_msg_msg *msg) +netifapi_do_netif_add(void *m) { + struct netifapi_msg_msg *msg = (struct netifapi_msg_msg*)m; + if (!netif_add( msg->netif, #if LWIP_IPV4 API_EXPR_REF(msg->msg.add.ipaddr), @@ -71,8 +124,10 @@ netifapi_do_netif_add(struct netifapi_msg_msg *msg) * Call netif_set_addr() inside the tcpip_thread context. */ static void -netifapi_do_netif_set_addr(struct netifapi_msg_msg *msg) +netifapi_do_netif_set_addr(void *m) { + struct netifapi_msg_msg *msg = (struct netifapi_msg_msg*)m; + netif_set_addr( msg->netif, API_EXPR_REF(msg->msg.add.ipaddr), API_EXPR_REF(msg->msg.add.netmask), @@ -87,8 +142,10 @@ netifapi_do_netif_set_addr(struct netifapi_msg_msg *msg) * tcpip_thread context. */ static void -netifapi_do_netif_common(struct netifapi_msg_msg *msg) +netifapi_do_netif_common(void *m) { + struct netifapi_msg_msg *msg = (struct netifapi_msg_msg*)m; + if (msg->msg.common.errtfunc != NULL) { msg->err = msg->msg.common.errtfunc(msg->netif); } else { diff --git a/src/api/tcpip.c b/src/api/tcpip.c index 95a97064..9ae817e5 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -99,12 +99,10 @@ tcpip_thread(void *arg) continue; } switch (msg->type) { -#if LWIP_NETCONN || LWIP_SOCKET case TCPIP_MSG_API: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); - msg->msg.apimsg->function(&(msg->msg.apimsg->msg)); + msg->msg.api.function(msg->msg.api.msg); break; -#endif /* LWIP_NETCONN || LWIP_SOCKET */ #if !LWIP_TCPIP_CORE_LOCKING_INPUT case TCPIP_MSG_INPKT: @@ -115,12 +113,6 @@ tcpip_thread(void *arg) #endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ -#if LWIP_NETIF_API - case TCPIP_MSG_NETIFAPI: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg)); - msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg)); - break; -#endif /* LWIP_NETIF_API */ #if LWIP_PPP_API case TCPIP_MSG_PPPAPI: @@ -318,6 +310,33 @@ tcpip_untimeout(sys_timeout_handler h, void *arg) } #endif /* LWIP_TCPIP_TIMEOUT */ + +/** + * Generic way to send an API message. + * + * @param fn Function to be called from TCPIP thread + * @param apimsg argument to API function + * @param sem Semaphore to wait on + * @return ERR_OK if the function was called, another err_t if not + */ +err_t +tcpip_send_api_msg(api_msg_fn fn, void *apimsg, sys_sem_t* sem) +{ + if (sys_mbox_valid_val(mbox)) { + TCPIP_MSG_VAR_DECLARE(msg); + + TCPIP_MSG_VAR_ALLOC(msg); + TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API; + TCPIP_MSG_VAR_REF(msg).msg.api.function = fn; + TCPIP_MSG_VAR_REF(msg).msg.api.msg = apimsg; + sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg)); + sys_arch_sem_wait(sem, 0); + TCPIP_MSG_VAR_FREE(msg); + return ERR_OK; + } + return ERR_VAL; +} + #if LWIP_NETCONN || LWIP_SOCKET /** * Call the lower part of a netconn_* function @@ -330,24 +349,17 @@ tcpip_untimeout(sys_timeout_handler h, void *arg) err_t tcpip_apimsg(struct api_msg *apimsg) { - 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_val(mbox)) { - TCPIP_MSG_VAR_ALLOC(msg); - TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API; - TCPIP_MSG_VAR_REF(msg).msg.apimsg = apimsg; #if LWIP_NETCONN_SEM_PER_THREAD - apimsg->msg.op_completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); - LWIP_ASSERT("netconn semaphore not initialized", - sys_sem_valid(apimsg->msg.op_completed_sem)); + apimsg->msg.op_completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); + LWIP_ASSERT("netconn semaphore not initialized", + sys_sem_valid(apimsg->msg.op_completed_sem)); #endif - sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg)); - sys_arch_sem_wait(LWIP_API_MSG_SEM(&apimsg->msg), 0); - TCPIP_MSG_VAR_FREE(msg); + + if (tcpip_send_api_msg(apimsg->function, &apimsg->msg, LWIP_API_MSG_SEM(&apimsg->msg)) == ERR_OK) { return apimsg->msg.err; } return ERR_VAL; @@ -355,60 +367,6 @@ tcpip_apimsg(struct api_msg *apimsg) #endif /* LWIP_NETCONN || LWIP_SOCKET */ -#if LWIP_NETIF_API -#if !LWIP_TCPIP_CORE_LOCKING -/** - * Much like tcpip_apimsg, but calls the lower part of a netifapi_* - * function. - * - * @param netifapimsg a struct containing the function to call and its parameters - * @return error code given back by the function that was called - */ -err_t -tcpip_netifapi(struct netifapi_msg* netifapimsg) -{ - TCPIP_MSG_VAR_DECLARE(msg); - - if (sys_mbox_valid_val(mbox)) { - 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; - } - - 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; -} -#else /* !LWIP_TCPIP_CORE_LOCKING */ -/** - * Call the lower part of a netifapi_* function - * This function has exclusive access to lwIP core code by locking it - * before the function is called. - * - * @param netifapimsg a struct containing the function to call and its parameters - * @return ERR_OK (only for compatibility fo tcpip_netifapi()) - */ -err_t -tcpip_netifapi_lock(struct netifapi_msg* netifapimsg) -{ - LOCK_TCPIP_CORE(); - netifapimsg->function(&(netifapimsg->msg)); - UNLOCK_TCPIP_CORE(); - return netifapimsg->msg.err; -} -#endif /* !LWIP_TCPIP_CORE_LOCKING */ -#endif /* LWIP_NETIF_API */ - #if LWIP_PPP_API #if !LWIP_TCPIP_CORE_LOCKING /** diff --git a/src/include/lwip/netifapi.h b/src/include/lwip/netifapi.h index 1d76ab11..58f16647 100644 --- a/src/include/lwip/netifapi.h +++ b/src/include/lwip/netifapi.h @@ -74,7 +74,7 @@ struct netifapi_msg_msg { }; struct netifapi_msg { - void (* function)(struct netifapi_msg_msg *msg); + void (* function)(void *msg); struct netifapi_msg_msg msg; }; diff --git a/src/include/lwip/priv/api_msg.h b/src/include/lwip/priv/api_msg.h index 909a925d..df3deef5 100644 --- a/src/include/lwip/priv/api_msg.h +++ b/src/include/lwip/priv/api_msg.h @@ -155,7 +155,7 @@ struct api_msg_msg { This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */ struct api_msg { /** function to execute in tcpip_thread context */ - void (* function)(struct api_msg_msg *msg); + void (* function)(void *msg); /** arguments for this function */ struct api_msg_msg msg; }; @@ -186,20 +186,20 @@ struct dns_api_msg { }; #endif /* LWIP_DNS */ -void lwip_netconn_do_newconn ( struct api_msg_msg *msg); -void lwip_netconn_do_delconn ( struct api_msg_msg *msg); -void lwip_netconn_do_bind ( struct api_msg_msg *msg); -void lwip_netconn_do_connect ( struct api_msg_msg *msg); -void lwip_netconn_do_disconnect ( struct api_msg_msg *msg); -void lwip_netconn_do_listen ( struct api_msg_msg *msg); -void lwip_netconn_do_send ( struct api_msg_msg *msg); -void lwip_netconn_do_recv ( struct api_msg_msg *msg); -void lwip_netconn_do_write ( struct api_msg_msg *msg); -void lwip_netconn_do_getaddr ( struct api_msg_msg *msg); -void lwip_netconn_do_close ( struct api_msg_msg *msg); -void lwip_netconn_do_shutdown ( struct api_msg_msg *msg); +void lwip_netconn_do_newconn (void *m); +void lwip_netconn_do_delconn (void *m); +void lwip_netconn_do_bind (void *m); +void lwip_netconn_do_connect (void *m); +void lwip_netconn_do_disconnect (void *m); +void lwip_netconn_do_listen (void *m); +void lwip_netconn_do_send (void *m); +void lwip_netconn_do_recv (void *m); +void lwip_netconn_do_write (void *m); +void lwip_netconn_do_getaddr (void *m); +void lwip_netconn_do_close (void *m); +void lwip_netconn_do_shutdown (void *m); #if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -void lwip_netconn_do_join_leave_group( struct api_msg_msg *msg); +void lwip_netconn_do_join_leave_group(void *m); #endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ #if LWIP_DNS diff --git a/src/include/lwip/priv/tcpip_priv.h b/src/include/lwip/priv/tcpip_priv.h index 3d716f2c..fb2d2f1b 100644 --- a/src/include/lwip/priv/tcpip_priv.h +++ b/src/include/lwip/priv/tcpip_priv.h @@ -38,7 +38,6 @@ #include "lwip/tcpip.h" #include "lwip/priv/api_msg.h" -#include "lwip/netifapi.h" #include "lwip/pppapi.h" #include "lwip/pbuf.h" #include "lwip/api.h" @@ -83,8 +82,6 @@ extern sys_mutex_t lock_tcpip_core; (e) = (m)->msg.err; \ } while(0) #define TCPIP_APIMSG_ACK(m) NETCONN_SET_SAFE_ERR((m)->conn, (m)->err) -#define TCPIP_NETIFAPI(m) tcpip_netifapi_lock(m) -#define TCPIP_NETIFAPI_ACK(m) #define TCPIP_PPPAPI(m) tcpip_pppapi_lock(m) #define TCPIP_PPPAPI_ACK(m) #else /* LWIP_TCPIP_CORE_LOCKING */ @@ -93,8 +90,6 @@ extern sys_mutex_t lock_tcpip_core; #define TCPIP_APIMSG_NOERR(m,f) do { (m)->function = f; tcpip_apimsg(m); } while(0) #define TCPIP_APIMSG(m,f,e) do { (m)->function = f; (e) = tcpip_apimsg(m); } while(0) #define TCPIP_APIMSG_ACK(m) do { NETCONN_SET_SAFE_ERR((m)->conn, (m)->err); sys_sem_signal(LWIP_API_MSG_SEM(m)); } while(0) -#define TCPIP_NETIFAPI(m) tcpip_netifapi(m) -#define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(&m->sem) #define TCPIP_PPPAPI(m) tcpip_pppapi(m) #define TCPIP_PPPAPI_ACK(m) sys_sem_signal(&m->sem) #endif /* LWIP_TCPIP_CORE_LOCKING */ @@ -136,13 +131,6 @@ extern sys_mutex_t lock_tcpip_core; err_t tcpip_apimsg(struct api_msg *apimsg); #endif /* LWIP_NETCONN || LWIP_SOCKET */ -#if LWIP_NETIF_API -err_t tcpip_netifapi(struct netifapi_msg *netifapimsg); -#if LWIP_TCPIP_CORE_LOCKING -err_t tcpip_netifapi_lock(struct netifapi_msg *netifapimsg); -#endif /* LWIP_TCPIP_CORE_LOCKING */ -#endif /* LWIP_NETIF_API */ - #if LWIP_PPP_API err_t tcpip_pppapi(struct pppapi_msg *pppapimsg); #if LWIP_TCPIP_CORE_LOCKING @@ -150,15 +138,12 @@ err_t tcpip_pppapi_lock(struct pppapi_msg *pppapimsg); #endif /* LWIP_TCPIP_CORE_LOCKING */ #endif /* LWIP_PPP_API */ +typedef void (*api_msg_fn)(void *msg); +err_t tcpip_send_api_msg(api_msg_fn fn, void *apimsg, sys_sem_t* sem); enum tcpip_msg_type { -#if LWIP_NETCONN || LWIP_SOCKET TCPIP_MSG_API, -#endif /* LWIP_NETCONN || LWIP_SOCKET */ TCPIP_MSG_INPKT, -#if LWIP_NETIF_API - TCPIP_MSG_NETIFAPI, -#endif /* LWIP_NETIF_API */ #if LWIP_PPP_API TCPIP_MSG_PPPAPI, #endif /* LWIP_PPP_API */ @@ -173,12 +158,10 @@ enum tcpip_msg_type { struct tcpip_msg { enum tcpip_msg_type type; union { -#if LWIP_NETCONN || LWIP_SOCKET - struct api_msg *apimsg; -#endif /* LWIP_NETCONN || LWIP_SOCKET */ -#if LWIP_NETIF_API - struct netifapi_msg *netifapimsg; -#endif /* LWIP_NETIF_API */ + struct { + api_msg_fn function; + void* msg; + } api; #if LWIP_PPP_API struct pppapi_msg *pppapimsg; #endif /* LWIP_PPP_API */