1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

gnrc_netreg: add arbitrary callback support

This commit is contained in:
Martine Lenders 2016-06-07 14:00:26 +02:00 committed by Martine Lenders
parent b84d955921
commit 97adff5eac
4 changed files with 105 additions and 5 deletions

View File

@ -12,6 +12,7 @@ PSEUDOMODULES += gnrc_ipv6_router
PSEUDOMODULES += gnrc_ipv6_router_default
PSEUDOMODULES += gnrc_netdev_default
PSEUDOMODULES += gnrc_neterr
PSEUDOMODULES += gnrc_netapi_callbacks
PSEUDOMODULES += gnrc_netapi_mbox
PSEUDOMODULES += gnrc_pktbuf
PSEUDOMODULES += gnrc_sixlowpan_border_router_default

View File

@ -36,6 +36,21 @@
* USEMODULE += gnrc_netapi_mbox
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* @}
*
* @defgroup net_gnrc_netapi_callbacks Callback extension
* @ingroup net_gnrc_netapi
* @brief Callback extension for @ref net_gnrc_netapi
* @{
* @details The submodule `gnrc_netapi_callbacks` provides an extension for
* callbacks to run GNRC thread-less.
*
* To use, add the module `gnrc_netapi_callbacks` to the `USEMODULE` macro in
* your application's Makefile:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
* USEMODULE += gnrc_netapi_callbacks
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* @}
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/

View File

@ -35,13 +35,16 @@
extern "C" {
#endif
#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(DOXYGEN)
#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(MODULE_GNRC_NETAPI_CALLBACKS) || \
defined(DOXYGEN)
typedef enum {
GNRC_NETREG_TYPE_DEFAULT = 0,
#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(DOXYGEN)
GNRC_NETREG_TYPE_MBOX,
#endif
#if defined(MODULE_GNRC_NETAPI_CALLBACKS) || defined(DOXYGEN)
GNRC_NETREG_TYPE_CB,
#endif
} gnrc_netreg_type_t;
#endif
@ -77,7 +80,7 @@ typedef enum {
* 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.
* @note Only available with @ref net_gnrc_netapi_mbox.
*
* @return An initialized netreg entry
*/
@ -86,6 +89,48 @@ typedef enum {
{ .mbox = mbox } }
#endif
#if defined(MODULE_GNRC_NETAPI_CALLBACKS) || defined(DOXYGEN)
/**
* @brief Initializes a netreg entry statically with callback
*
* @param[in] demux_ctx The @ref gnrc_netreg_entry_t::demux_ctx "demux context"
* for the netreg entry
* @param[in] cb Target callback for the registry entry
*
* @note Only available with @ref net_gnrc_netapi_callbacks.
*
* @return An initialized netreg entry
*/
#define GNRC_NETREG_ENTRY_INIT_CB(demux_ctx, cbd) { NULL, demux_ctx, \
GNRC_NETREG_TYPE_CB, \
{ .cbd = cbd } }
/**
* @brief Packet handler callback for netreg entries with callback.
*
* @pre `cmd` $\in$ { @ref GNRC_NETAPI_MSG_TYPE_RCV, @ref GNRC_NETAPI_MSG_TYPE_SND }
*
* @note Only available with @ref net_gnrc_netapi_callbacks.
*
* @param[in] cmd @ref net_gnrc_netapi command type. Must be either
* @ref GNRC_NETAPI_MSG_TYPE_SND or
* @ref GNRC_NETAPI_MSG_TYPE_RCV
* @param[in] pkt The packet to handle.
* @param[in] ctx Application context.
*/
typedef void (*gnrc_netreg_entry_cb_t)(uint16_t cmd, gnrc_pktsnip_t *pkt,
void *ctx);
/**
* @brief Callback + Context descriptor
* @note Only available with @ref net_gnrc_netapi_callbacks.
*/
typedef struct {
gnrc_netreg_entry_cb_t cb; /**< the callback */
void *ctx; /**< application context for the callback */
} gnrc_netreg_entry_cbd_t;
#endif
/**
* @brief Entry to the @ref net_gnrc_netreg
*/
@ -105,7 +150,8 @@ typedef struct gnrc_netreg_entry {
* ports in UDP/TCP, or similar.
*/
uint32_t demux_ctx;
#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(DOXYGEN)
#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(MODULE_GNRC_NETAPI_CALLBACKS) || \
defined(DOXYGEN)
/**
* @brief Type of the registry entry
*
@ -124,6 +170,15 @@ typedef struct gnrc_netreg_entry {
*/
mbox_t *mbox;
#endif
#if defined(MODULE_GNRC_NETAPI_CALLBACKS) || defined(DOXYGEN)
/**
* @brief Target callback for the registry entry
*
* @note Only available with @ref net_gnrc_netapi_callbacks.
*/
gnrc_netreg_entry_cbd_t *cbd;
#endif
} target; /**< Target for the registry entry */
} gnrc_netreg_entry_t;
@ -147,7 +202,7 @@ static inline void gnrc_netreg_entry_init_pid(gnrc_netreg_entry_t *entry,
{
entry->next = NULL;
entry->demux_ctx = demux_ctx;
#ifdef MODULE_GNRC_NETAPI_MBOX
#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(MODULE_GNRC_NETAPI_CALLBACKS)
entry->type = GNRC_NETREG_TYPE_DEFAULT;
#endif
entry->target.pid = pid;
@ -175,6 +230,28 @@ static inline void gnrc_netreg_entry_init_mbox(gnrc_netreg_entry_t *entry,
}
#endif
#if defined(MODULE_GNRC_NETAPI_CALLBACKS) || defined(DOXYGEN)
/**
* @brief Initializes a netreg entry dynamically with callback
*
* @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 callback for the registry entry
*
* @note Only available with @ref net_gnrc_netapi_callbacks.
*/
static inline void gnrc_netreg_entry_init_cb(gnrc_netreg_entry_t *entry,
uint32_t demux_ctx,
gnrc_netreg_entry_cbd_t *cbd)
{
entry->next = NULL;
entry->demux_ctx = demux_ctx;
entry->type = GNRC_NETREG_TYPE_CB;
entry->target.cbd = cbd;
}
#endif
/**
* @brief Registers a thread to the registry.
*

View File

@ -102,7 +102,7 @@ int gnrc_netapi_dispatch(gnrc_nettype_t type, uint32_t demux_ctx,
gnrc_pktbuf_hold(pkt, numof - 1);
while (sendto) {
#ifdef MODULE_GNRC_NETAPI_MBOX
#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(MODULE_GNRC_NETAPI_CALLBACKS)
int release = 0;
switch (sendto->type) {
case GNRC_NETREG_TYPE_DEFAULT:
@ -111,12 +111,19 @@ int gnrc_netapi_dispatch(gnrc_nettype_t type, uint32_t demux_ctx,
release = 1;
}
break;
#ifdef MODULE_GNRC_NETAPI_MBOX
case GNRC_NETREG_TYPE_MBOX:
if (_snd_rcv_mbox(sendto->target.mbox, cmd, pkt) < 1) {
/* unable to dispatch packet */
release = 1;
}
break;
#endif
#ifdef MODULE_GNRC_NETAPI_CALLBACKS
case GNRC_NETREG_TYPE_CB:
sendto->target.cbd->cb(cmd, pkt, sendto->target.cbd->ctx);
break;
#endif
default:
/* unknown dispatch type */
release = 1;