From 8c3dc66ad882bad808ab5d7c95ff8a40921fa866 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Thu, 17 Oct 2019 16:56:38 +0200 Subject: [PATCH] gnrc_sixlowpan_frag: factor-out and rename fragmentation buffer The name `fragment_msg` or `frag_msg`/`msg_frag` always to me was a bit misplaced, as it basically implements an asynchronous fragmentation buffer and doesn't necessarily have anything to do with messages. This change 1. changes the name to `fb` (for fragmentation buffer) 2. factors its code out to its own sub-module so it can be re-used by other 6LoWPAN fragmentation schemes like [Selective Fragment Recovery] [Selective Fragment Recovery]: https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-05 --- Makefile.dep | 6 + sys/include/net/gnrc/sixlowpan/config.h | 8 +- sys/include/net/gnrc/sixlowpan/frag.h | 80 +----------- sys/include/net/gnrc/sixlowpan/frag/fb.h | 115 ++++++++++++++++++ sys/net/gnrc/Makefile | 3 + .../network_layer/sixlowpan/frag/fb/Makefile | 3 + .../frag/fb/gnrc_sixlowpan_frag_fb.c | 54 ++++++++ .../sixlowpan/frag/gnrc_sixlowpan_frag.c | 105 +++++++--------- .../frag/vrb/gnrc_sixlowpan_frag_vrb.c | 13 +- .../network_layer/sixlowpan/gnrc_sixlowpan.c | 27 ++-- .../tests-gnrc_sixlowpan_frag_vrb.c | 9 +- 11 files changed, 253 insertions(+), 170 deletions(-) create mode 100644 sys/include/net/gnrc/sixlowpan/frag/fb.h create mode 100644 sys/net/gnrc/network_layer/sixlowpan/frag/fb/Makefile create mode 100644 sys/net/gnrc/network_layer/sixlowpan/frag/fb/gnrc_sixlowpan_frag_fb.c diff --git a/Makefile.dep b/Makefile.dep index c3301ba5a3..19d50e66d2 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -212,15 +212,21 @@ endif ifneq (,$(filter gnrc_sixlowpan_frag,$(USEMODULE))) USEMODULE += gnrc_sixlowpan + USEMODULE += gnrc_sixlowpan_frag_fb USEMODULE += gnrc_sixlowpan_frag_rb endif +ifneq (,$(filter gnrc_sixlowpan_frag_fb,$(USEMODULE))) + USEMODULE += core_msg +endif + ifneq (,$(filter gnrc_sixlowpan_frag_rb,$(USEMODULE))) USEMODULE += xtimer endif ifneq (,$(filter gnrc_sixlowpan_frag_vrb,$(USEMODULE))) USEMODULE += xtimer + USEMODULE += gnrc_sixlowpan_frag_fb endif ifneq (,$(filter gnrc_sixlowpan_iphc,$(USEMODULE))) diff --git a/sys/include/net/gnrc/sixlowpan/config.h b/sys/include/net/gnrc/sixlowpan/config.h index ed1ed36ab0..d90303f1f2 100644 --- a/sys/include/net/gnrc/sixlowpan/config.h +++ b/sys/include/net/gnrc/sixlowpan/config.h @@ -51,14 +51,14 @@ extern "C" { /** * @brief Number of datagrams that can be fragmented simultaneously * - * This determines the number of @ref gnrc_sixlowpan_msg_frag_t instances + * This determines the number of @ref gnrc_sixlowpan_frag_fb_t instances * available. * * @note Only applicable with - * [gnrc_sixlowpan_frag](@ref net_gnrc_sixlowpan_frag) module + * [gnrc_sixlowpan_frag_fb](@ref net_gnrc_sixlowpan_frag_fb) module */ -#ifndef GNRC_SIXLOWPAN_MSG_FRAG_SIZE -#define GNRC_SIXLOWPAN_MSG_FRAG_SIZE (1U) +#ifndef GNRC_SIXLOWPAN_FRAG_FB_SIZE +#define GNRC_SIXLOWPAN_FRAG_FB_SIZE (1U) #endif /** diff --git a/sys/include/net/gnrc/sixlowpan/frag.h b/sys/include/net/gnrc/sixlowpan/frag.h index b0cd698661..d561c70c47 100644 --- a/sys/include/net/gnrc/sixlowpan/frag.h +++ b/sys/include/net/gnrc/sixlowpan/frag.h @@ -26,15 +26,14 @@ #define NET_GNRC_SIXLOWPAN_FRAG_H #include -#include #include "byteorder.h" -#include "msg.h" #include "net/gnrc/pkt.h" #include "net/gnrc/netif/hdr.h" #ifdef MODULE_GNRC_SIXLOWPAN_FRAG_HINT #include "net/gnrc/sixlowpan/frag/hint.h" #endif /* MODULE_GNRC_SIXLOWPAN_FRAG_HINT */ +#include "net/gnrc/sixlowpan/frag/fb.h" #include "net/gnrc/sixlowpan/internal.h" #include "net/ieee802154.h" #include "net/sixlowpan.h" @@ -43,34 +42,6 @@ extern "C" { #endif -/** - * @name Message types - * @{ - */ -/** - * @brief Message type for passing one 6LoWPAN fragment down the network stack - */ -#define GNRC_SIXLOWPAN_MSG_FRAG_SND (0x0225) -/** @} */ - -/** - * @brief Definition of 6LoWPAN fragmentation type. - */ -typedef struct { - gnrc_pktsnip_t *pkt; /**< Pointer to the IPv6 packet to be fragmented */ - uint16_t datagram_size; /**< Length of just the (uncompressed) IPv6 packet to be fragmented */ - uint16_t tag; /**< Tag used for the fragment */ - uint16_t offset; /**< Offset of the Nth fragment from the beginning of the - * payload datagram */ -#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_HINT - /** - * @brief Hint for the size (smaller than link-layer PDU) for the next - * fragment to sent - */ - gnrc_sixlowpan_frag_hint_t hint; -#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 @@ -81,7 +52,7 @@ 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 */ + * no @ref gnrc_sixlowpan_frag_fb_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 */ @@ -96,26 +67,17 @@ typedef struct { gnrc_sixlowpan_frag_stats_t *gnrc_sixlowpan_frag_stats_get(void); #endif -/** - * @brief Allocates a @ref gnrc_sixlowpan_msg_frag_t object - * - * @return A @ref gnrc_sixlowpan_msg_frag_t if available - * @return NULL, otherwise - */ -gnrc_sixlowpan_msg_frag_t *gnrc_sixlowpan_msg_frag_get(void); - /** * @brief Sends a packet fragmented * * @pre `ctx != NULL` - * @pre gnrc_sixlowpan_msg_frag_t::pkt of @p ctx is equal to @p pkt or + * @pre gnrc_sixlowpan_frag_fb_t::pkt of @p ctx is equal to @p pkt or * `pkt == NULL`. * * @param[in] pkt A packet. May be NULL. - * @param[in] ctx Message containing status of the 6LoWPAN fragmentation - * progress. Expected to be of type - * @ref gnrc_sixlowpan_msg_frag_t, with - * gnrc_sixlowpan_msg_frag_t set to @p pkt. Must not be + * @param[in] ctx A fragmentation buffer entry. Expected to be of type + * @ref gnrc_sixlowpan_frag_fb_t, with + * gnrc_sixlowpan_frag_fb_t set to @p pkt. Must not be * NULL. * @param[in] page Current 6Lo dispatch parsing page. */ @@ -130,36 +92,6 @@ void gnrc_sixlowpan_frag_send(gnrc_pktsnip_t *pkt, void *ctx, unsigned page); */ void gnrc_sixlowpan_frag_recv(gnrc_pktsnip_t *pkt, void *ctx, unsigned page); -/** - * @brief Generate a new datagram tag for sending - * - * @return A new datagram tag. - */ -uint16_t gnrc_sixlowpan_frag_next_tag(void); - -/** - * @brief Sends a message to pass a further fragment down the network stack - * - * @see GNRC_SIXLOWPAN_MSG_FRAG_SND - * - * @param[in] fragment_msg A @ref gnrc_sixlowpan_msg_frag_t object - * - * @return true, when the message was sent - * @return false when sending the message failed. - */ -static inline bool gnrc_sixlowpan_frag_send_msg(gnrc_sixlowpan_msg_frag_t *fragment_msg) -{ - msg_t msg; - - msg.content.ptr = fragment_msg; - msg.type = GNRC_SIXLOWPAN_MSG_FRAG_SND; -#ifdef TEST_SUITES - return (msg_try_send(&msg, gnrc_sixlowpan_get_pid()) > 0); -#else - return (msg_send_to_self(&msg) != 0); -#endif -} - #ifdef __cplusplus } #endif diff --git a/sys/include/net/gnrc/sixlowpan/frag/fb.h b/sys/include/net/gnrc/sixlowpan/frag/fb.h new file mode 100644 index 0000000000..d12e5426d0 --- /dev/null +++ b/sys/include/net/gnrc/sixlowpan/frag/fb.h @@ -0,0 +1,115 @@ +/* + * 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. + */ + +/** + * @defgroup net_gnrc_sixlowpan_frag_fb 6LoWPAN fragmentation buffer + * @ingroup net_gnrc_sixlowpan_frag + * @brief Buffer for asynchronous 6LoWPAN fragmentation + * @{ + * + * @file + * @brief Fragmentation buffer definitions + * + * @author Martine Lenders + */ +#ifndef NET_GNRC_SIXLOWPAN_FRAG_FB_H +#define NET_GNRC_SIXLOWPAN_FRAG_FB_H + +#include +#include + +#include "msg.h" +#include "net/gnrc/pkt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Message type for passing one 6LoWPAN fragment down the network stack + */ +#define GNRC_SIXLOWPAN_FRAG_FB_SND_MSG (0x0225) + +/** + * @brief 6LoWPAN fragmentation buffer entry. + */ +typedef struct { + gnrc_pktsnip_t *pkt; /**< Pointer to the IPv6 packet to be fragmented */ + uint16_t datagram_size; /**< Length of just the (uncompressed) IPv6 packet to be fragmented */ + uint16_t tag; /**< Tag used for the fragment */ + uint16_t offset; /**< Offset of the Nth fragment from the beginning of the + * payload datagram */ +#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_HINT + /** + * @brief Hint for the size (smaller than link-layer PDU) for the next + * fragment to sent + */ + gnrc_sixlowpan_frag_hint_t hint; +#endif /* MODULE_GNRC_SIXLOWPAN_FRAG_HINT */ +} gnrc_sixlowpan_frag_fb_t; + +#ifdef TEST_SUITES +/** + * @brief Reset fragmentation buffer + * + * @note Only available with test + */ +void gnrc_sixlowpan_frag_fb_reset(void); +#endif + +/** + * @brief Allocates a fragmentation buffer entry + * + * @return A fragmentation buffer entry if available + * @return NULL, otherwise + */ +gnrc_sixlowpan_frag_fb_t *gnrc_sixlowpan_frag_fb_get(void); + +/** + * @brief Generate a new datagram tag for sending + * + * @return A new datagram tag. + */ +uint16_t gnrc_sixlowpan_frag_fb_next_tag(void); + +#if defined(TEST_SUITES) && !defined(DOXYGEN) +#include "kernel_types.h" + +/* can't include `net/sixlowpan.h` as this would create a cyclical include */ +extern kernel_pid_t gnrc_sixlowpan_get_pid(void); +#endif + +/** + * @brief Sends a message to pass a further fragment down the network stack + * + * @see GNRC_SIXLOWPAN_MSG_FRAG_SND + * + * @param[in] fbuf A fragmentation buffer entry + *] + * @return true, when the message was sent + * @return false when sending the message failed. + */ +static inline bool gnrc_sixlowpan_frag_fb_send(gnrc_sixlowpan_frag_fb_t *fbuf) +{ + msg_t msg; + + msg.content.ptr = fbuf; + msg.type = GNRC_SIXLOWPAN_FRAG_FB_SND_MSG; +#ifdef TEST_SUITES + return (msg_try_send(&msg, gnrc_sixlowpan_get_pid()) > 0); +#else + return (msg_send_to_self(&msg) != 0); +#endif +} + +#ifdef __cplusplus +} +#endif + +#endif /* NET_GNRC_SIXLOWPAN_FRAG_FB_H */ +/** @} */ diff --git a/sys/net/gnrc/Makefile b/sys/net/gnrc/Makefile index 31da5312a0..cea412af33 100644 --- a/sys/net/gnrc/Makefile +++ b/sys/net/gnrc/Makefile @@ -91,6 +91,9 @@ endif ifneq (,$(filter gnrc_sixlowpan_frag,$(USEMODULE))) DIRS += network_layer/sixlowpan/frag endif +ifneq (,$(filter gnrc_sixlowpan_frag_fb,$(USEMODULE))) + DIRS += network_layer/sixlowpan/frag/fb +endif ifneq (,$(filter gnrc_sixlowpan_frag_rb,$(USEMODULE))) DIRS += network_layer/sixlowpan/frag/rb endif diff --git a/sys/net/gnrc/network_layer/sixlowpan/frag/fb/Makefile b/sys/net/gnrc/network_layer/sixlowpan/frag/fb/Makefile new file mode 100644 index 0000000000..b159a4b595 --- /dev/null +++ b/sys/net/gnrc/network_layer/sixlowpan/frag/fb/Makefile @@ -0,0 +1,3 @@ +MODULE := gnrc_sixlowpan_frag_fb + +include $(RIOTBASE)/Makefile.base diff --git a/sys/net/gnrc/network_layer/sixlowpan/frag/fb/gnrc_sixlowpan_frag_fb.c b/sys/net/gnrc/network_layer/sixlowpan/frag/fb/gnrc_sixlowpan_frag_fb.c new file mode 100644 index 0000000000..dce81ca13b --- /dev/null +++ b/sys/net/gnrc/network_layer/sixlowpan/frag/fb/gnrc_sixlowpan_frag_fb.c @@ -0,0 +1,54 @@ +/* + * 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 + +#include "net/gnrc/sixlowpan/config.h" +#include "net/gnrc/sixlowpan/frag/fb.h" +#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS +#include "net/gnrc/sixlowpan/frag/stats.h" +#endif + +static gnrc_sixlowpan_frag_fb_t _fbs[GNRC_SIXLOWPAN_FRAG_FB_SIZE]; +static uint16_t _current_tag; + +#ifdef TEST_SUITES +void gnrc_sixlowpan_frag_fb_reset(void) +{ + memset(_fbs, 0, sizeof(_fbs)); + _current_tag = 0; +} +#endif + +gnrc_sixlowpan_frag_fb_t *gnrc_sixlowpan_frag_fb_get(void) +{ + for (unsigned i = 0; i < GNRC_SIXLOWPAN_FRAG_FB_SIZE; i++) { + if (_fbs[i].pkt == NULL) { + return &_fbs[i]; + } + } +#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS + gnrc_sixlowpan_frag_stats_get()->frag_full++; +#endif + return NULL; +} + +uint16_t gnrc_sixlowpan_frag_fb_next_tag(void) +{ + return (++_current_tag); +} + +/** @} */ 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 b37817123f..8bdc68b427 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 @@ -30,14 +30,11 @@ #define ENABLE_DEBUG (0) #include "debug.h" -static gnrc_sixlowpan_msg_frag_t _fragment_msg[GNRC_SIXLOWPAN_MSG_FRAG_SIZE]; - #if ENABLE_DEBUG /* For PRIu16 etc. */ #include #endif -static uint16_t _current_tag; static inline uint16_t _floor8(uint16_t length) { @@ -50,41 +47,41 @@ static inline size_t _min(size_t a, size_t b) } static inline uint8_t _max_frag_size(gnrc_netif_t *iface, - gnrc_sixlowpan_msg_frag_t *fragment_msg) + gnrc_sixlowpan_frag_fb_t *fbuf) { #ifdef MODULE_GNRC_SIXLOWPAN_FRAG_HINT - if (fragment_msg->hint.fragsz > 0) { + if (fbuf->hint.fragsz > 0) { /* account for rounding down to 8*/ - return (fragment_msg->hint.fragsz & 0x7) - ? (fragment_msg->hint.fragsz + 8U) - : fragment_msg->hint.fragsz; + return (fbuf->hint.fragsz & 0x7) + ? (fbuf->hint.fragsz + 8U) + : fbuf->hint.fragsz; } #endif /* MODULE_GNRC_SIXLOWPAN_FRAG_HINT */ - (void)fragment_msg; + (void)fbuf; return iface->sixlo.max_frag_size; } -static inline int _payload_diff(gnrc_sixlowpan_msg_frag_t *fragment_msg, +static inline int _payload_diff(gnrc_sixlowpan_frag_fb_t *fbuf, size_t payload_len) { #ifdef MODULE_GNRC_SIXLOWPAN_FRAG_HINT - if (fragment_msg->hint.fragsz > 0) { - return fragment_msg->hint.fragsz_uncomp - fragment_msg->hint.fragsz; + if (fbuf->hint.fragsz > 0) { + return fbuf->hint.fragsz_uncomp - fbuf->hint.fragsz; } #endif /* MODULE_GNRC_SIXLOWPAN_FRAG_HINT */ - return (fragment_msg->datagram_size - payload_len); + return (fbuf->datagram_size - payload_len); } static gnrc_pktsnip_t *_build_frag_pkt(gnrc_pktsnip_t *pkt, - gnrc_sixlowpan_msg_frag_t *fragment_msg, + gnrc_sixlowpan_frag_fb_t *fbuf, size_t payload_len, size_t size) { sixlowpan_frag_t *frag_hdr; gnrc_netif_hdr_t *netif_hdr = pkt->data, *new_netif_hdr; gnrc_pktsnip_t *netif, *frag; #ifdef MODULE_GNRC_SIXLOWPAN_FRAG_HINT - size_t fragment_size = ((fragment_msg->hint.fragsz > 0) && - (fragment_msg->offset == 0)) + size_t fragment_size = ((fbuf->hint.fragsz > 0) && + (fbuf->offset == 0)) ? size /* we want the calculated fragment size * to include full IPHC header */ : _min(size, payload_len); @@ -115,8 +112,8 @@ static gnrc_pktsnip_t *_build_frag_pkt(gnrc_pktsnip_t *pkt, } frag_hdr = frag->data; /* XXX: truncation of datagram_size > 4095 may happen here */ - frag_hdr->disp_size = byteorder_htons(fragment_msg->datagram_size); - frag_hdr->tag = byteorder_htons(fragment_msg->tag); + frag_hdr->disp_size = byteorder_htons(fbuf->datagram_size); + frag_hdr->tag = byteorder_htons(fbuf->tag); LL_PREPEND(frag, netif); @@ -141,25 +138,25 @@ static uint16_t _copy_pkt_to_frag(uint8_t *data, const gnrc_pktsnip_t *pkt, } static uint16_t _send_1st_fragment(gnrc_netif_t *iface, - gnrc_sixlowpan_msg_frag_t *fragment_msg, + gnrc_sixlowpan_frag_fb_t *fbuf, size_t payload_len) { - gnrc_pktsnip_t *frag, *pkt = fragment_msg->pkt; + gnrc_pktsnip_t *frag, *pkt = fbuf->pkt; sixlowpan_frag_t *hdr; uint8_t *data; /* payload_len: actual size of the packet vs * datagram_size: size of the uncompressed IPv6 packet */ - int payload_diff = _payload_diff(fragment_msg, payload_len); + int payload_diff = _payload_diff(fbuf, payload_len); uint16_t local_offset; /* virtually add payload_diff to flooring to account for offset (must be divisable by 8) * in uncompressed datagram */ - uint16_t max_frag_size = _floor8(_max_frag_size(iface, fragment_msg) + + uint16_t max_frag_size = _floor8(_max_frag_size(iface, fbuf) + payload_diff - sizeof(sixlowpan_frag_t)) - payload_diff; DEBUG("6lo frag: determined max_frag_size = %" PRIu16 "\n", max_frag_size); - frag = _build_frag_pkt(pkt, fragment_msg, payload_len, + frag = _build_frag_pkt(pkt, fbuf, payload_len, max_frag_size + sizeof(sixlowpan_frag_t)); if (frag == NULL) { @@ -179,19 +176,19 @@ static uint16_t _send_1st_fragment(gnrc_netif_t *iface, DEBUG("6lo frag: send first fragment (datagram size: %u, " "datagram tag: %" PRIu16 ", fragment size: %" PRIu16 ")\n", - fragment_msg->datagram_size, fragment_msg->tag, local_offset); + fbuf->datagram_size, fbuf->tag, local_offset); gnrc_sixlowpan_dispatch_send(frag, NULL, 0); return local_offset; } static uint16_t _send_nth_fragment(gnrc_netif_t *iface, - gnrc_sixlowpan_msg_frag_t *fragment_msg, + gnrc_sixlowpan_frag_fb_t *fbuf, size_t payload_len) { - gnrc_pktsnip_t *frag, *pkt = fragment_msg->pkt; + gnrc_pktsnip_t *frag, *pkt = fbuf->pkt; sixlowpan_frag_n_t *hdr; uint8_t *data; - uint16_t local_offset = 0, offset_count = 0, offset = fragment_msg->offset; + uint16_t local_offset = 0, offset_count = 0, offset = fbuf->offset; /* since dispatches aren't supposed to go into subsequent fragments, we need not account * for payload difference as for the first fragment */ uint16_t max_frag_size = _floor8(iface->sixlo.max_frag_size - @@ -199,7 +196,7 @@ static uint16_t _send_nth_fragment(gnrc_netif_t *iface, DEBUG("6lo frag: determined max_frag_size = %" PRIu16 "\n", max_frag_size); - frag = _build_frag_pkt(pkt, fragment_msg, + frag = _build_frag_pkt(pkt, fbuf, payload_len - offset + sizeof(sixlowpan_frag_n_t), max_frag_size + sizeof(sixlowpan_frag_n_t)); @@ -211,7 +208,7 @@ static uint16_t _send_nth_fragment(gnrc_netif_t *iface, data = (uint8_t *)(hdr + 1); hdr->disp_size.u8[0] |= SIXLOWPAN_FRAG_N_DISP; /* don't mention payload diff in offset */ - hdr->offset = (uint8_t)((offset + _payload_diff(fragment_msg, + hdr->offset = (uint8_t)((offset + _payload_diff(fbuf, payload_len)) >> 3); pkt = pkt->next; /* don't copy netif header */ while ((pkt != NULL) && (offset_count != offset)) { /* go to offset */ @@ -240,72 +237,59 @@ static uint16_t _send_nth_fragment(gnrc_netif_t *iface, DEBUG("6lo frag: send subsequent fragment (datagram size: %u, " "datagram tag: %" PRIu16 ", offset: %" PRIu8 " (%u bytes), " "fragment size: %" PRIu16 ")\n", - fragment_msg->datagram_size, fragment_msg->tag, hdr->offset, + fbuf->datagram_size, fbuf->tag, hdr->offset, hdr->offset << 3, local_offset); gnrc_sixlowpan_dispatch_send(frag, NULL, 0); return local_offset; } -gnrc_sixlowpan_msg_frag_t *gnrc_sixlowpan_msg_frag_get(void) -{ - for (unsigned i = 0; i < GNRC_SIXLOWPAN_MSG_FRAG_SIZE; i++) { - if (_fragment_msg[i].pkt == NULL) { - return &_fragment_msg[i]; - } - } -#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS - gnrc_sixlowpan_frag_stats_get()->frag_full++; -#endif - return NULL; -} - void gnrc_sixlowpan_frag_send(gnrc_pktsnip_t *pkt, void *ctx, unsigned page) { assert(ctx != NULL); - gnrc_sixlowpan_msg_frag_t *fragment_msg = ctx; + gnrc_sixlowpan_frag_fb_t *fbuf = ctx; gnrc_netif_t *iface; uint16_t res; /* payload_len: actual size of the packet vs * datagram_size: size of the uncompressed IPv6 packet */ - size_t payload_len = gnrc_pkt_len(fragment_msg->pkt->next); + size_t payload_len = gnrc_pkt_len(fbuf->pkt->next); - assert((fragment_msg->pkt == pkt) || (pkt == NULL)); + assert((fbuf->pkt == pkt) || (pkt == NULL)); (void)page; (void)pkt; - iface = gnrc_netif_hdr_get_netif(fragment_msg->pkt->data); + iface = gnrc_netif_hdr_get_netif(fbuf->pkt->data); #if defined(DEVELHELP) && ENABLE_DEBUG if (iface == NULL) { DEBUG("6lo frag: iface == NULL, expect segmentation fault.\n"); /* remove original packet from packet buffer */ - gnrc_pktbuf_release(fragment_msg->pkt); + gnrc_pktbuf_release(fbuf->pkt); /* 6LoWPAN free for next fragmentation */ - fragment_msg->pkt = NULL; + fbuf->pkt = NULL; return; } #endif /* Check whether to send the first or an Nth fragment */ - if (fragment_msg->offset == 0) { - if ((res = _send_1st_fragment(iface, fragment_msg, payload_len)) == 0) { + if (fbuf->offset == 0) { + if ((res = _send_1st_fragment(iface, fbuf, payload_len)) == 0) { /* error sending first fragment */ DEBUG("6lo frag: error sending 1st fragment\n"); goto error; } } /* (offset + (datagram_size - payload_len) < datagram_size) simplified */ - else if (fragment_msg->offset < payload_len) { - if ((res = _send_nth_fragment(iface, fragment_msg, payload_len)) == 0) { + else if (fbuf->offset < payload_len) { + if ((res = _send_nth_fragment(iface, fbuf, payload_len)) == 0) { /* error sending subsequent fragment */ DEBUG("6lo frag: error sending subsequent fragment" - "(offset = %u)\n", fragment_msg->offset); + "(offset = %u)\n", fbuf->offset); goto error; } } else { goto error; } - fragment_msg->offset += res; - if (!gnrc_sixlowpan_frag_send_msg(fragment_msg)) { + fbuf->offset += res; + if (!gnrc_sixlowpan_frag_fb_send(fbuf)) { DEBUG("6lo frag: message queue full, can't issue next fragment " "sending\n"); goto error; @@ -313,8 +297,8 @@ void gnrc_sixlowpan_frag_send(gnrc_pktsnip_t *pkt, void *ctx, unsigned page) thread_yield(); return; error: - gnrc_pktbuf_release(fragment_msg->pkt); - fragment_msg->pkt = NULL; + gnrc_pktbuf_release(fbuf->pkt); + fbuf->pkt = NULL; } void gnrc_sixlowpan_frag_recv(gnrc_pktsnip_t *pkt, void *ctx, unsigned page) @@ -351,9 +335,4 @@ void gnrc_sixlowpan_frag_recv(gnrc_pktsnip_t *pkt, void *ctx, unsigned page) gnrc_pktbuf_release(netif_hdr); } -uint16_t gnrc_sixlowpan_frag_next_tag(void) -{ - return (++_current_tag); -} - /** @} */ 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 cf6f1bfdc5..9a78e26aca 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 @@ -21,6 +21,7 @@ #include "net/gnrc/netif.h" #include "xtimer.h" +#include "net/gnrc/sixlowpan/frag/fb.h" #include "net/gnrc/sixlowpan/frag/vrb.h" #define ENABLE_DEBUG (0) @@ -33,16 +34,6 @@ static char addr_str[IPV6_ADDR_MAX_STR_LEN]; static char addr_str[3 * IEEE802154_LONG_ADDRESS_LEN]; #endif /* MODULE_GNRC_IPV6_NIB */ -#if !defined(MODULE_GNRC_SIXLOWPAN_FRAG) && defined(TEST_SUITES) -/* mock for e.g. testing */ -uint16_t tag = 0; - -uint16_t gnrc_sixlowpan_frag_next_tag(void) -{ - return tag++; -} -#endif /* !defined(MODULE_GNRC_SIXLOWPAN_FRAG) && defined(TEST_SUITES) */ - static inline bool _equal_index(const gnrc_sixlowpan_frag_vrb_t *vrbe, const uint8_t *src, size_t src_len, unsigned tag) @@ -73,7 +64,7 @@ gnrc_sixlowpan_frag_vrb_t *gnrc_sixlowpan_frag_vrb_add( vrbe->super = *base; vrbe->out_netif = out_netif; memcpy(vrbe->super.dst, out_dst, out_dst_len); - vrbe->out_tag = gnrc_sixlowpan_frag_next_tag(); + vrbe->out_tag = gnrc_sixlowpan_frag_fb_next_tag(); vrbe->super.dst_len = out_dst_len; DEBUG("6lo vrb: creating entry (%s, ", gnrc_netif_addr_to_str(vrbe->super.src, diff --git a/sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c b/sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c index 923037fd8d..3c77d07643 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c +++ b/sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c @@ -121,25 +121,25 @@ void gnrc_sixlowpan_multiplex_by_size(gnrc_pktsnip_t *pkt, else if (orig_datagram_size <= SIXLOWPAN_FRAG_MAX_LEN) { DEBUG("6lo: Send fragmented (%u > %u)\n", (unsigned int)datagram_size, netif->sixlo.max_frag_size); - gnrc_sixlowpan_msg_frag_t *fragment_msg; + gnrc_sixlowpan_frag_fb_t *fbuf; - fragment_msg = gnrc_sixlowpan_msg_frag_get(); - if (fragment_msg == NULL) { + fbuf = gnrc_sixlowpan_frag_fb_get(); + if (fbuf == NULL) { DEBUG("6lo: Not enough resources to fragment packet. " "Dropping packet\n"); gnrc_pktbuf_release_error(pkt, ENOMEM); return; } - fragment_msg->pkt = pkt; - fragment_msg->datagram_size = orig_datagram_size; - fragment_msg->tag = gnrc_sixlowpan_frag_next_tag(); + fbuf->pkt = pkt; + fbuf->datagram_size = orig_datagram_size; + fbuf->tag = gnrc_sixlowpan_frag_fb_next_tag(); /* Sending the first fragment has an offset==0 */ - fragment_msg->offset = 0; + fbuf->offset = 0; #ifdef MODULE_GNRC_SIXLOWPAN_FRAG_HINT - fragment_msg->hint.fragsz = 0; + fbuf->hint.fragsz = 0; #endif - gnrc_sixlowpan_frag_send(pkt, fragment_msg, page); + gnrc_sixlowpan_frag_send(pkt, fbuf, page); } #endif else { @@ -343,10 +343,15 @@ static void *_event_loop(void *args) reply.content.value = -ENOTSUP; msg_reply(&msg, &reply); break; -#ifdef MODULE_GNRC_SIXLOWPAN_FRAG - case GNRC_SIXLOWPAN_MSG_FRAG_SND: +#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_FB + case GNRC_SIXLOWPAN_FRAG_FB_SND_MSG: DEBUG("6lo: send fragmented event received\n"); +#ifdef MODULE_GNRC_SIXLOWPAN_FRAG gnrc_sixlowpan_frag_send(NULL, msg.content.ptr, 0); +#else /* MODULE_GNRC_SIXLOWPAN_FRAG_FB */ + DEBUG("6lo: No fragmentation implementation available to sent\n"); + assert(false); +#endif /* MODULE_GNRC_SIXLOWPAN_FRAG_FB */ break; #endif #ifdef MODULE_GNRC_SIXLOWPAN_FRAG_RB diff --git a/tests/unittests/tests-gnrc_sixlowpan_frag_vrb/tests-gnrc_sixlowpan_frag_vrb.c b/tests/unittests/tests-gnrc_sixlowpan_frag_vrb/tests-gnrc_sixlowpan_frag_vrb.c index 8b827522d6..d00a54ee0d 100644 --- a/tests/unittests/tests-gnrc_sixlowpan_frag_vrb/tests-gnrc_sixlowpan_frag_vrb.c +++ b/tests/unittests/tests-gnrc_sixlowpan_frag_vrb/tests-gnrc_sixlowpan_frag_vrb.c @@ -18,6 +18,7 @@ #include "embUnit/embUnit.h" +#include "net/gnrc/sixlowpan/frag/fb.h" #include "net/gnrc/sixlowpan/frag/vrb.h" #include "xtimer.h" @@ -31,8 +32,6 @@ #define TEST_DST_LEN (8U) #define TEST_TAG (26U) -extern uint16_t tag; - /* The interface is not used for anything by the VRB (it just is kept as a * reference for forwarding) so an uninitialized one is enough */ static gnrc_netif_t _dummy_netif; @@ -58,14 +57,13 @@ static uint8_t _out_dst[] = TEST_OUT_DST; static void set_up(void) { gnrc_sixlowpan_frag_vrb_reset(); - tag = 0; + gnrc_sixlowpan_frag_fb_reset(); } static void test_vrb_add__success(void) { gnrc_sixlowpan_frag_vrb_t *res; - tag = TEST_TAG_INITIAL; TEST_ASSERT_NOT_NULL((res = gnrc_sixlowpan_frag_vrb_add(&_base, &_dummy_netif, _out_dst, @@ -88,15 +86,12 @@ static void test_vrb_add__success(void) TEST_ASSERT_EQUAL_INT(sizeof(_out_dst), res->super.dst_len); TEST_ASSERT_MESSAGE(memcmp(_out_dst, res->super.dst, sizeof(_out_dst)) == 0, "TEST_DST != res->super.dst"); - TEST_ASSERT_EQUAL_INT(TEST_TAG_INITIAL, res->out_tag); - TEST_ASSERT(TEST_TAG_INITIAL != tag); } static void test_vrb_add__duplicate(void) { gnrc_sixlowpan_frag_vrb_t *res1, *res2; - tag = TEST_TAG_INITIAL; TEST_ASSERT_NOT_NULL((res1 = gnrc_sixlowpan_frag_vrb_add(&_base, &_dummy_netif, _out_dst,