diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index d110900ff1..f9a3ccb894 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -32,6 +32,7 @@ PSEUDOMODULES += gnrc_sixloenc PSEUDOMODULES += gnrc_sixlowpan_border_router_default PSEUDOMODULES += gnrc_sixlowpan_default PSEUDOMODULES += gnrc_sixlowpan_frag_hint +PSEUDOMODULES += gnrc_sixlowpan_frag_stats PSEUDOMODULES += gnrc_sixlowpan_iphc_nhc PSEUDOMODULES += gnrc_sixlowpan_nd_border_router PSEUDOMODULES += gnrc_sixlowpan_router diff --git a/sys/include/net/gnrc/sixlowpan/frag.h b/sys/include/net/gnrc/sixlowpan/frag.h index 53108e71e6..aeb9275b8a 100644 --- a/sys/include/net/gnrc/sixlowpan/frag.h +++ b/sys/include/net/gnrc/sixlowpan/frag.h @@ -138,6 +138,31 @@ typedef struct { #endif /* MODULE_GNRC_SIXLOWPAN_FRAG_HINT */ } gnrc_sixlowpan_msg_frag_t; +#if defined(MODULE_GNRC_SIXLOWPAN_FRAG_STATS) || DOXYGEN +/** + * @brief Statistics on fragmentation and reassembly + * + * @note Only available with the `gnrc_sixlowpan_frag_stats` module + */ +typedef struct { + unsigned rbuf_full; /**< counts the number of events where the + * reassembly buffer is full */ + unsigned frag_full; /**< counts the number of events that there where + * no @ref gnrc_sixlowpan_msg_frag_t available */ +#if defined(MODULE_GNRC_SIXLOWPAN_FRAG_VRB) || DOXYGEN + unsigned vrb_full; /**< counts the number of events where the virtual + * reassembly buffer is full */ +#endif +} gnrc_sixlowpan_frag_stats_t; + +/** + * @brief Get the current statistics on fragmentation and reassembly + * + * @return The current statistics on fragmentation and reassembly + */ +gnrc_sixlowpan_frag_stats_t *gnrc_sixlowpan_frag_stats_get(void); +#endif + /** * @brief Allocates a @ref gnrc_sixlowpan_msg_frag_t object * diff --git a/sys/net/gnrc/network_layer/sixlowpan/frag/gnrc_sixlowpan_frag.c b/sys/net/gnrc/network_layer/sixlowpan/frag/gnrc_sixlowpan_frag.c index c5dd9e9278..3f454a3099 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/frag/gnrc_sixlowpan_frag.c +++ b/sys/net/gnrc/network_layer/sixlowpan/frag/gnrc_sixlowpan_frag.c @@ -274,6 +274,9 @@ gnrc_sixlowpan_msg_frag_t *gnrc_sixlowpan_msg_frag_get(void) return &_fragment_msg[i]; } } +#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS + gnrc_sixlowpan_frag_stats_get()->frag_full++; +#endif return NULL; } diff --git a/sys/net/gnrc/network_layer/sixlowpan/frag/rbuf.c b/sys/net/gnrc/network_layer/sixlowpan/frag/rbuf.c index 9ca95f9375..63ad48ed71 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/frag/rbuf.c +++ b/sys/net/gnrc/network_layer/sixlowpan/frag/rbuf.c @@ -82,6 +82,15 @@ enum { RBUF_ADD_DUPLICATE, }; +#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS +static gnrc_sixlowpan_frag_stats_t _stats; + +gnrc_sixlowpan_frag_stats_t *gnrc_sixlowpan_frag_stats_get(void) +{ + return &_stats; +} +#endif + static int _check_fragments(gnrc_sixlowpan_rbuf_base_t *entry, size_t frag_size, size_t offset) { @@ -348,8 +357,15 @@ static gnrc_sixlowpan_rbuf_t *_rbuf_get(const void *src, size_t src_len, gnrc_pktbuf_release(oldest->pkt); rbuf_rm(oldest); res = oldest; +#if GNRC_SIXLOWPAN_FRAG_RBUF_AGGRESSIVE_OVERRIDE && \ + defined(MODULE_GNRC_SIXLOWPAN_FRAG_STATS) + _stats.rbuf_full++; +#endif } else { +#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS + _stats.rbuf_full++; +#endif return NULL; } } diff --git a/sys/net/gnrc/network_layer/sixlowpan/frag/vrb/gnrc_sixlowpan_frag_vrb.c b/sys/net/gnrc/network_layer/sixlowpan/frag/vrb/gnrc_sixlowpan_frag_vrb.c index 18ddf349d0..a2abf73a10 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/frag/vrb/gnrc_sixlowpan_frag_vrb.c +++ b/sys/net/gnrc/network_layer/sixlowpan/frag/vrb/gnrc_sixlowpan_frag_vrb.c @@ -73,6 +73,11 @@ gnrc_sixlowpan_frag_vrb_t *gnrc_sixlowpan_frag_vrb_add( break; } } +#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS + if (vrbe == NULL) { + gnrc_sixlowpan_frag_stats_get()->vrb_full++; + } +#endif return vrbe; }