diff --git a/Makefile.dep b/Makefile.dep index f596f883f685a2711445b0dbc292ad5a268d39d2..802f98b2aa5c2420bc887b8ec414158cd4a38090 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -57,6 +57,10 @@ ifneq (,$(filter gnrc_conn_udp,$(USEMODULE))) USEMODULE += gnrc_udp endif +ifneq (,$(filter gnrc_netapi_mbox,$(USEMODULE))) + USEMODULE += core_mbox +endif + ifneq (,$(filter netdev2_tap,$(USEMODULE))) USEMODULE += netif USEMODULE += netdev2_eth diff --git a/Makefile.pseudomodules b/Makefile.pseudomodules index 9e02789345f0f5ba206cdcb6d32c5bfdab52d3ff..438fa415ad90cc9e8ff7c3b359cd07b921676906 100644 --- a/Makefile.pseudomodules +++ b/Makefile.pseudomodules @@ -12,6 +12,7 @@ PSEUDOMODULES += gnrc_ipv6_router PSEUDOMODULES += gnrc_ipv6_router_default PSEUDOMODULES += gnrc_netdev_default PSEUDOMODULES += gnrc_neterr +PSEUDOMODULES += gnrc_netapi_mbox PSEUDOMODULES += gnrc_pktbuf PSEUDOMODULES += gnrc_sixlowpan_border_router_default PSEUDOMODULES += gnrc_sixlowpan_default diff --git a/sys/include/net/gnrc/netapi.h b/sys/include/net/gnrc/netapi.h index 52ce4ae7a945dbe3de89895efcb9cd268fe47245..63ea497b7820bd80643c52782ffa9ff81cba057e 100644 --- a/sys/include/net/gnrc/netapi.h +++ b/sys/include/net/gnrc/netapi.h @@ -21,6 +21,21 @@ * @file * @brief Generic interface to communicate with GNRC modules * + * @defgroup net_gnrc_netapi_mbox Mailbox IPC extension + * @ingroup net_gnrc_netapi + * @brief @ref core_mbox "Mailbox IPC" extension for @ref net_gnrc_netapi + * @{ + * + * @details The submodule `gnrc_netapi_mbox` provides an extension for + * @ref core_mbox "Mailbox IPC". + * + * To use, add the module `gnrc_netapi_mbox` to the `USEMODULE` macro in your + * application's Makefile: + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk} + * USEMODULE += gnrc_netapi_mbox + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * @} * @author Martine Lenders <mlenders@inf.fu-berlin.de> * @author Hauke Petersen <hauke.petersen@fu-berlin.de> */ diff --git a/sys/include/net/gnrc/netreg.h b/sys/include/net/gnrc/netreg.h index 0b7b48a86f30406031be5fc90eb8b74792467bba..d040f332c95cb0a2fba4cb0519c01140b88ce23a 100644 --- a/sys/include/net/gnrc/netreg.h +++ b/sys/include/net/gnrc/netreg.h @@ -27,10 +27,24 @@ #include "net/gnrc/nettype.h" #include "net/gnrc/pkt.h" +#ifdef MODULE_GNRC_NETAPI_MBOX +#include "mbox.h" +#endif + #ifdef __cplusplus extern "C" { #endif +#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(DOXYGEN) +typedef enum { + GNRC_NETREG_TYPE_DEFAULT = 0, +#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(DOXYGEN) + GNRC_NETREG_TYPE_MBOX, +#endif + GNRC_NETREG_TYPE_CB, +} gnrc_netreg_type_t; +#endif + /** * @brief Demux context value to get all packets of a certain type. * @@ -47,7 +61,30 @@ extern "C" { * * @return An initialized netreg entry */ -#define GNRC_NETREG_ENTRY_INIT_PID(demux_ctx, pid) { NULL, demux_ctx, pid } +#ifdef MODULE_GNRC_NETAPI_MBOX +#define GNRC_NETREG_ENTRY_INIT_PID(demux_ctx, pid) { NULL, demux_ctx, \ + GNRC_NETREG_TYPE_DEFAULT, \ + { pid } } +#else +#define GNRC_NETREG_ENTRY_INIT_PID(demux_ctx, pid) { NULL, demux_ctx, { pid } } +#endif + +#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(DOXYGEN) +/** + * @brief Initializes a netreg entry statically with mbox + * + * @param[in] demux_ctx The @ref gnrc_netreg_entry_t::demux_ctx "demux context" + * for the netreg entry + * @param[in] mbox Target @ref core_mbox "mailbox" for the registry entry + * + * @note Only available with @ref net_gnrc_netreg_extra. + * + * @return An initialized netreg entry + */ +#define GNRC_NETREG_ENTRY_INIT_MBOX(demux_ctx, mbox) { NULL, demux_ctx, \ + GNRC_NETREG_TYPE_MBOX, \ + { .mbox = mbox } } +#endif /** * @brief Entry to the @ref net_gnrc_netreg @@ -68,7 +105,26 @@ typedef struct gnrc_netreg_entry { * ports in UDP/TCP, or similar. */ uint32_t demux_ctx; - kernel_pid_t pid; /**< The PID of the registering thread */ +#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(DOXYGEN) + /** + * @brief Type of the registry entry + * + * @note Only available with @ref net_gnrc_netapi_mbox or + * @ref net_gnrc_netapi_callbacks. + */ + gnrc_netreg_type_t type; +#endif + union { + kernel_pid_t pid; /**< The PID of the registering thread */ +#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(DOXYGEN) + /** + * @brief Target @ref core_mbox "mailbox" for the registry entry + * + * @note Only available with @ref net_gnrc_netapi_mbox. + */ + mbox_t *mbox; +#endif + } target; /**< Target for the registry entry */ } gnrc_netreg_entry_t; /** @@ -91,9 +147,34 @@ static inline void gnrc_netreg_entry_init_pid(gnrc_netreg_entry_t *entry, { entry->next = NULL; entry->demux_ctx = demux_ctx; - entry->pid = pid; +#ifdef MODULE_GNRC_NETAPI_MBOX + entry->type = GNRC_NETREG_TYPE_DEFAULT; +#endif + entry->target.pid = pid; } +#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(DOXYGEN) +/** + * @brief Initializes a netreg entry dynamically with mbox + * + * @param[out] entry A netreg entry + * @param[in] demux_ctx The @ref gnrc_netreg_entry_t::demux_ctx "demux context" + * for the netreg entry + * @param[in] mbox Target @ref core_mbox "mailbox" for the registry entry + * + * @note Only available with @ref net_gnrc_netapi_mbox. + */ +static inline void gnrc_netreg_entry_init_mbox(gnrc_netreg_entry_t *entry, + uint32_t demux_ctx, + mbox_t *mbox) +{ + entry->next = NULL; + entry->demux_ctx = demux_ctx; + entry->type = GNRC_NETREG_TYPE_MBOX; + entry->target.mbox = mbox; +} +#endif + /** * @brief Registers a thread to the registry. * diff --git a/sys/net/gnrc/netapi/gnrc_netapi.c b/sys/net/gnrc/netapi/gnrc_netapi.c index a6294cbcabb8988b52e8f37e6dd6ffb49530f582..5f80302524108256c0dedd64d6b57f1929482550 100644 --- a/sys/net/gnrc/netapi/gnrc_netapi.c +++ b/sys/net/gnrc/netapi/gnrc_netapi.c @@ -18,6 +18,7 @@ * @} */ +#include "mbox.h" #include "msg.h" #include "net/gnrc/netreg.h" #include "net/gnrc/pktbuf.h" @@ -74,6 +75,22 @@ static inline int _snd_rcv(kernel_pid_t pid, uint16_t type, gnrc_pktsnip_t *pkt) return ret; } +#ifdef MODULE_GNRC_NETAPI_MBOX +static inline int _snd_rcv_mbox(mbox_t *mbox, uint16_t type, gnrc_pktsnip_t *pkt) +{ + msg_t msg; + /* set the outgoing message's fields */ + msg.type = type; + msg.content.ptr = (void *)pkt; + /* send message */ + int ret = mbox_try_put(mbox, &msg); + if (ret < 1) { + DEBUG("gnrc_netapi: dropped message to %p (was full)\n", mbox); + } + return ret; +} +#endif + int gnrc_netapi_dispatch(gnrc_nettype_t type, uint32_t demux_ctx, uint16_t cmd, gnrc_pktsnip_t *pkt) { @@ -85,10 +102,35 @@ int gnrc_netapi_dispatch(gnrc_nettype_t type, uint32_t demux_ctx, gnrc_pktbuf_hold(pkt, numof - 1); while (sendto) { - if (_snd_rcv(sendto->pid, cmd, pkt) < 1) { +#ifdef MODULE_GNRC_NETAPI_MBOX + int release = 0; + switch (sendto->type) { + case GNRC_NETREG_TYPE_DEFAULT: + if (_snd_rcv(sendto->target.pid, cmd, pkt) < 1) { + /* unable to dispatch packet */ + release = 1; + } + break; + case GNRC_NETREG_TYPE_MBOX: + if (_snd_rcv_mbox(sendto->target.mbox, cmd, pkt) < 1) { + /* unable to dispatch packet */ + release = 1; + } + break; + default: + /* unknown dispatch type */ + release = 1; + break; + } + if (release) { + gnrc_pktbuf_release(pkt); + } +#else + if (_snd_rcv(sendto->target.pid, cmd, pkt) < 1) { /* unable to dispatch packet */ gnrc_pktbuf_release(pkt); } +#endif sendto = gnrc_netreg_getnext(sendto); } } diff --git a/sys/net/gnrc/netreg/gnrc_netreg.c b/sys/net/gnrc/netreg/gnrc_netreg.c index 7effd16f120e34b447008d3314d643ac476f783d..a01c557c72909ab9ad8056a2001754c611acc62a 100644 --- a/sys/net/gnrc/netreg/gnrc_netreg.c +++ b/sys/net/gnrc/netreg/gnrc_netreg.c @@ -37,8 +37,16 @@ void gnrc_netreg_init(void) int gnrc_netreg_register(gnrc_nettype_t type, gnrc_netreg_entry_t *entry) { +#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(MODULE_GNRC_NETAPI_CALLBACKS) +#ifdef DEVELHELP /* only threads with a message queue are allowed to register at gnrc */ - assert(sched_threads[entry->pid]->msg_array); + assert((entry->type != GNRC_NETREG_TYPE_DEFAULT) || + sched_threads[entry->target.pid]->msg_array); +#endif +#else + /* only threads with a message queue are allowed to register at gnrc */ + assert(sched_threads[entry->target.pid]->msg_array); +#endif if (_INVALID_TYPE(type)) { return -EINVAL;