Skip to content
Snippets Groups Projects
Commit 97adff5e authored by Martine Lenders's avatar Martine Lenders
Browse files

gnrc_netreg: add arbitrary callback support

parent b84d9559
No related branches found
No related tags found
No related merge requests found
...@@ -12,6 +12,7 @@ PSEUDOMODULES += gnrc_ipv6_router ...@@ -12,6 +12,7 @@ PSEUDOMODULES += gnrc_ipv6_router
PSEUDOMODULES += gnrc_ipv6_router_default PSEUDOMODULES += gnrc_ipv6_router_default
PSEUDOMODULES += gnrc_netdev_default PSEUDOMODULES += gnrc_netdev_default
PSEUDOMODULES += gnrc_neterr PSEUDOMODULES += gnrc_neterr
PSEUDOMODULES += gnrc_netapi_callbacks
PSEUDOMODULES += gnrc_netapi_mbox PSEUDOMODULES += gnrc_netapi_mbox
PSEUDOMODULES += gnrc_pktbuf PSEUDOMODULES += gnrc_pktbuf
PSEUDOMODULES += gnrc_sixlowpan_border_router_default PSEUDOMODULES += gnrc_sixlowpan_border_router_default
......
...@@ -36,6 +36,21 @@ ...@@ -36,6 +36,21 @@
* USEMODULE += gnrc_netapi_mbox * 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 Martine Lenders <mlenders@inf.fu-berlin.de>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de> * @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/ */
......
...@@ -35,13 +35,16 @@ ...@@ -35,13 +35,16 @@
extern "C" { extern "C" {
#endif #endif
#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(DOXYGEN) #if defined(MODULE_GNRC_NETAPI_MBOX) || defined(MODULE_GNRC_NETAPI_CALLBACKS) || \
defined(DOXYGEN)
typedef enum { typedef enum {
GNRC_NETREG_TYPE_DEFAULT = 0, GNRC_NETREG_TYPE_DEFAULT = 0,
#if defined(MODULE_GNRC_NETAPI_MBOX) || defined(DOXYGEN) #if defined(MODULE_GNRC_NETAPI_MBOX) || defined(DOXYGEN)
GNRC_NETREG_TYPE_MBOX, GNRC_NETREG_TYPE_MBOX,
#endif #endif
#if defined(MODULE_GNRC_NETAPI_CALLBACKS) || defined(DOXYGEN)
GNRC_NETREG_TYPE_CB, GNRC_NETREG_TYPE_CB,
#endif
} gnrc_netreg_type_t; } gnrc_netreg_type_t;
#endif #endif
...@@ -77,7 +80,7 @@ typedef enum { ...@@ -77,7 +80,7 @@ typedef enum {
* for the netreg entry * for the netreg entry
* @param[in] mbox Target @ref core_mbox "mailbox" for the registry 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 * @return An initialized netreg entry
*/ */
...@@ -86,6 +89,48 @@ typedef enum { ...@@ -86,6 +89,48 @@ typedef enum {
{ .mbox = mbox } } { .mbox = mbox } }
#endif #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 * @brief Entry to the @ref net_gnrc_netreg
*/ */
...@@ -105,7 +150,8 @@ typedef struct gnrc_netreg_entry { ...@@ -105,7 +150,8 @@ typedef struct gnrc_netreg_entry {
* ports in UDP/TCP, or similar. * ports in UDP/TCP, or similar.
*/ */
uint32_t demux_ctx; 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 * @brief Type of the registry entry
* *
...@@ -124,6 +170,15 @@ typedef struct gnrc_netreg_entry { ...@@ -124,6 +170,15 @@ typedef struct gnrc_netreg_entry {
*/ */
mbox_t *mbox; mbox_t *mbox;
#endif #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 */ } target; /**< Target for the registry entry */
} gnrc_netreg_entry_t; } gnrc_netreg_entry_t;
...@@ -147,7 +202,7 @@ static inline void gnrc_netreg_entry_init_pid(gnrc_netreg_entry_t *entry, ...@@ -147,7 +202,7 @@ static inline void gnrc_netreg_entry_init_pid(gnrc_netreg_entry_t *entry,
{ {
entry->next = NULL; entry->next = NULL;
entry->demux_ctx = demux_ctx; 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; entry->type = GNRC_NETREG_TYPE_DEFAULT;
#endif #endif
entry->target.pid = pid; entry->target.pid = pid;
...@@ -175,6 +230,28 @@ static inline void gnrc_netreg_entry_init_mbox(gnrc_netreg_entry_t *entry, ...@@ -175,6 +230,28 @@ static inline void gnrc_netreg_entry_init_mbox(gnrc_netreg_entry_t *entry,
} }
#endif #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. * @brief Registers a thread to the registry.
* *
......
...@@ -102,7 +102,7 @@ int gnrc_netapi_dispatch(gnrc_nettype_t type, uint32_t demux_ctx, ...@@ -102,7 +102,7 @@ int gnrc_netapi_dispatch(gnrc_nettype_t type, uint32_t demux_ctx,
gnrc_pktbuf_hold(pkt, numof - 1); gnrc_pktbuf_hold(pkt, numof - 1);
while (sendto) { while (sendto) {
#ifdef MODULE_GNRC_NETAPI_MBOX #if defined(MODULE_GNRC_NETAPI_MBOX) || defined(MODULE_GNRC_NETAPI_CALLBACKS)
int release = 0; int release = 0;
switch (sendto->type) { switch (sendto->type) {
case GNRC_NETREG_TYPE_DEFAULT: case GNRC_NETREG_TYPE_DEFAULT:
...@@ -111,12 +111,19 @@ int gnrc_netapi_dispatch(gnrc_nettype_t type, uint32_t demux_ctx, ...@@ -111,12 +111,19 @@ int gnrc_netapi_dispatch(gnrc_nettype_t type, uint32_t demux_ctx,
release = 1; release = 1;
} }
break; break;
#ifdef MODULE_GNRC_NETAPI_MBOX
case GNRC_NETREG_TYPE_MBOX: case GNRC_NETREG_TYPE_MBOX:
if (_snd_rcv_mbox(sendto->target.mbox, cmd, pkt) < 1) { if (_snd_rcv_mbox(sendto->target.mbox, cmd, pkt) < 1) {
/* unable to dispatch packet */ /* unable to dispatch packet */
release = 1; release = 1;
} }
break; 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: default:
/* unknown dispatch type */ /* unknown dispatch type */
release = 1; release = 1;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment