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
This commit is contained in:
Dirk Ziegelmeier 2016-03-07 19:57:51 +01:00
parent 5cf802eda0
commit af1978fa4e
6 changed files with 150 additions and 128 deletions

View File

@ -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 {

View File

@ -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 {

View File

@ -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
/**

View File

@ -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;
};

View File

@ -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

View File

@ -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 */