diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index d110900ff1bf..f9a3ccb894e1 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 53108e71e6fd..aeb9275b8aa7 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 c5dd9e927876..3f454a309959 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 9ca95f9375dd..63ad48ed719f 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 18ddf349d0b7..a2abf73a102d 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; } diff --git a/sys/shell/commands/Makefile b/sys/shell/commands/Makefile index 81d3dd062adb..05fabdbf6866 100644 --- a/sys/shell/commands/Makefile +++ b/sys/shell/commands/Makefile @@ -54,6 +54,9 @@ ifneq (,$(filter gnrc_ipv6_nib_6lbr,$(USEMODULE))) SRC += sc_gnrc_6ctx.c endif endif +ifneq (,$(filter gnrc_sixlowpan_frag_stats,$(USEMODULE))) + SRC += sc_gnrc_6lo_frag_stats.c +endif ifneq (,$(filter saul_reg,$(USEMODULE))) SRC += sc_saul_reg.c endif diff --git a/sys/shell/commands/sc_gnrc_6lo_frag_stats.c b/sys/shell/commands/sc_gnrc_6lo_frag_stats.c new file mode 100644 index 000000000000..6a553607cf19 --- /dev/null +++ b/sys/shell/commands/sc_gnrc_6lo_frag_stats.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2019 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @{ + * + * @file + * @author Martine Lenders + */ + +#include + +#include "net/gnrc/sixlowpan/frag.h" + +int _gnrc_6lo_frag_stats(int argc, char **argv) +{ + gnrc_sixlowpan_frag_stats_t *stats = gnrc_sixlowpan_frag_stats_get(); + + (void)argc; + (void)argv; + printf("rbuf full: %u\n", stats->rbuf_full); + printf("frag full: %u\n", stats->frag_full); +#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_VRB + printf("VRB full: %u\n", stats->vrb_full); +#endif + return 0; +} + +/** @} */ diff --git a/sys/shell/commands/shell_commands.c b/sys/shell/commands/shell_commands.c index fe29ee948062..78e703f6dd80 100644 --- a/sys/shell/commands/shell_commands.c +++ b/sys/shell/commands/shell_commands.c @@ -117,6 +117,12 @@ extern int _gnrc_6ctx(int argc, char **argv); #endif #endif +#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS +#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS +extern int _gnrc_6lo_frag_stats(int argc, char **argv); +#endif +#endif + #ifdef MODULE_CCN_LITE_UTILS extern int _ccnl_open(int argc, char **argv); extern int _ccnl_content(int argc, char **argv); @@ -225,6 +231,9 @@ const shell_command_t _shell_command_list[] = { {"6ctx", "6LoWPAN context configuration tool", _gnrc_6ctx }, #endif #endif +#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS + {"6lo_frag", "6LoWPAN fragment statistics", _gnrc_6lo_frag_stats }, +#endif #ifdef MODULE_SAUL_REG {"saul", "interact with sensors and actuators using SAUL", _saul }, #endif