-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #11000 from miri64/gnrc_sixlowpan_frag/new/vrb
gnrc_sixlowpan_frag: initial import of the VRB
- Loading branch information
Showing
11 changed files
with
654 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/* | ||
* 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_vrb Virtual reassembly buffer | ||
* @ingroup net_gnrc_sixlowpan_frag | ||
* @brief Virtual reassembly buffer | ||
* @{ | ||
* | ||
* @file | ||
* @brief Virtual reassembly buffer definitions | ||
* @see https://tools.ietf.org/html/draft-ietf-lwig-6lowpan-virtual-reassembly-01 | ||
* | ||
* @author Martine Lenders <[email protected]> | ||
*/ | ||
#ifndef NET_GNRC_SIXLOWPAN_FRAG_VRB_H | ||
#define NET_GNRC_SIXLOWPAN_FRAG_VRB_H | ||
|
||
#include <stddef.h> | ||
#include <stdbool.h> | ||
#include <stdint.h> | ||
|
||
#include "net/gnrc/netif.h" | ||
#include "net/gnrc/sixlowpan/config.h" | ||
#include "net/gnrc/sixlowpan/frag.h" | ||
#include "timex.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @brief Representation of the virtual reassembly buffer entry | ||
*/ | ||
typedef struct { | ||
gnrc_sixlowpan_rbuf_base_t super; /**< base type */ | ||
|
||
/** | ||
* @brief Link-layer destination address to which the fragments are | ||
* supposed to be forwarded to | ||
*/ | ||
uint8_t out_dst[IEEE802154_LONG_ADDRESS_LEN]; | ||
/** | ||
* @brief Outgoing interface to gnrc_sixlowpan_frag_vrb_t::out_dst | ||
*/ | ||
gnrc_netif_t *out_netif; | ||
/** | ||
* @brief Outgoing tag to gnrc_sixlowpan_frag_vrb_t::out_dst | ||
*/ | ||
uint16_t out_tag; | ||
/** | ||
* @brief Length of gnrc_sixlowpan_frag_vrb_t::out_dst | ||
*/ | ||
uint8_t out_dst_len; | ||
} gnrc_sixlowpan_frag_vrb_t; | ||
|
||
/** | ||
* @brief Adds a new reassembly buffer entry | ||
* | ||
* @param[in] base Base data of the datagram. Must not be `NULL`. | ||
* @param[in] out_netif Network interface that is out-going to @p out_dst. | ||
* @param[in] out_dst Link-layer destination address to which to forward | ||
* fragments identified by @p base. Must not be `NULL`. | ||
* @param[in] out_dst_len Length of @p out_dst. Must be greater than 0. | ||
* | ||
* @pre `base != NULL` | ||
* @pre `out_dst != NULL` | ||
* @pre `out_dst_len > 0` | ||
* | ||
* @return A new VRB entry. | ||
* @return NULL, if VRB is full. | ||
*/ | ||
gnrc_sixlowpan_frag_vrb_t *gnrc_sixlowpan_frag_vrb_add( | ||
const gnrc_sixlowpan_rbuf_base_t *base, | ||
gnrc_netif_t *out_netif, const uint8_t *out_dst, size_t out_dst_len); | ||
|
||
/** | ||
* @brief Checks timeouts and removes entries if necessary | ||
*/ | ||
void gnrc_sixlowpan_frag_vrb_gc(void); | ||
|
||
/** | ||
* @brief Gets a VRB entry | ||
* | ||
* @param[in] src Link-layer source address of the original fragment. | ||
* @param[in] src_len Length of @p src. | ||
* @param[in] dst Link-layer destination address of the original | ||
* fragment. | ||
* @param[in] dst_len Length of @p dst. | ||
* @param[in] datagram_size The original fragment's datagram size. | ||
* @param[in] src_tag Tag of the original fragment. | ||
* | ||
* @return The VRB entry identified by the given parameters. | ||
* @return NULL, if there is no entry in the VRB that could be identified | ||
* by the given parameters. | ||
*/ | ||
gnrc_sixlowpan_frag_vrb_t *gnrc_sixlowpan_frag_vrb_get( | ||
const uint8_t *src, size_t src_len, | ||
const uint8_t *dst, size_t dst_len, | ||
size_t datagram_size, unsigned src_tag); | ||
|
||
/** | ||
* @brief Removes an entry from the VRB | ||
* | ||
* @param[in] vrb A VRB entry | ||
*/ | ||
static inline void gnrc_sixlowpan_frag_vrb_rm(gnrc_sixlowpan_frag_vrb_t *vrb) | ||
{ | ||
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG | ||
gnrc_sixlowpan_frag_rbuf_base_rm(&vrb->super); | ||
#elif defined(TEST_SUITES) | ||
/* for testing just zero datagram_size */ | ||
vrb->super.datagram_size = 0; | ||
#endif /* MODULE_GNRC_SIXLOWPAN_FRAG */ | ||
} | ||
|
||
/** | ||
* @brief Determines if a VRB entry is empty | ||
* | ||
* @param[in] vrb A VRB entry | ||
* | ||
* @return true, if @p vrb entry is empty. | ||
* @return false, if @p vrb entry is not empty. | ||
*/ | ||
static inline bool gnrc_sixlowpan_frag_vrb_entry_empty(gnrc_sixlowpan_frag_vrb_t *vrb) | ||
{ | ||
return (vrb->super.datagram_size == 0); | ||
} | ||
|
||
#if defined(TEST_SUITES) || defined(DOXYGEN) | ||
/** | ||
* @brief Resets the VRB to a clean state | ||
* | ||
* @note Only available when @ref TEST_SUITES is defined | ||
*/ | ||
void gnrc_sixlowpan_frag_vrb_reset(void); | ||
#endif | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* NET_GNRC_SIXLOWPAN_FRAG_VRB_H */ | ||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
MODULE := gnrc_sixlowpan_frag_vrb | ||
|
||
include $(RIOTBASE)/Makefile.base |
137 changes: 137 additions & 0 deletions
137
sys/net/gnrc/network_layer/sixlowpan/frag/vrb/gnrc_sixlowpan_frag_vrb.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/* | ||
* 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 <[email protected]> | ||
*/ | ||
|
||
#include "net/ieee802154.h" | ||
#include "xtimer.h" | ||
|
||
#include "net/gnrc/sixlowpan/frag/vrb.h" | ||
|
||
#define ENABLE_DEBUG (0) | ||
#include "debug.h" | ||
|
||
static gnrc_sixlowpan_frag_vrb_t _vrb[GNRC_SIXLOWPAN_FRAG_VRB_SIZE]; | ||
static char l2addr_str[3 * IEEE802154_LONG_ADDRESS_LEN]; | ||
|
||
#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) */ | ||
|
||
gnrc_sixlowpan_frag_vrb_t *gnrc_sixlowpan_frag_vrb_add( | ||
const gnrc_sixlowpan_rbuf_base_t *base, | ||
gnrc_netif_t *out_netif, const uint8_t *out_dst, size_t out_dst_len) | ||
{ | ||
gnrc_sixlowpan_frag_vrb_t *vrbe = NULL; | ||
|
||
assert(base != NULL); | ||
assert(out_netif != NULL); | ||
assert(out_dst != NULL); | ||
assert(out_dst_len > 0); | ||
for (unsigned i = 0; i < GNRC_SIXLOWPAN_FRAG_VRB_SIZE; i++) { | ||
gnrc_sixlowpan_frag_vrb_t *ptr = &_vrb[i]; | ||
|
||
if (gnrc_sixlowpan_frag_vrb_entry_empty(ptr) || | ||
(memcmp(&ptr->super, base, sizeof(ptr->super)) == 0)) { | ||
vrbe = ptr; | ||
if (gnrc_sixlowpan_frag_vrb_entry_empty(vrbe)) { | ||
vrbe->super = *base; | ||
vrbe->out_netif = out_netif; | ||
memcpy(vrbe->out_dst, out_dst, out_dst_len); | ||
vrbe->out_tag = gnrc_sixlowpan_frag_next_tag(); | ||
vrbe->out_dst_len = out_dst_len; | ||
DEBUG("6lo vrb: creating entry (%s, ", | ||
gnrc_netif_addr_to_str(vrbe->super.src, | ||
vrbe->super.src_len, | ||
l2addr_str)); | ||
DEBUG("%s, %u, %u) => ", | ||
gnrc_netif_addr_to_str(vrbe->super.dst, | ||
vrbe->super.dst_len, | ||
l2addr_str), | ||
(unsigned)vrbe->super.datagram_size, vrbe->super.tag); | ||
DEBUG("(%s, %u)\n", | ||
gnrc_netif_addr_to_str(vrbe->out_dst, | ||
vrbe->out_dst_len, | ||
l2addr_str), vrbe->out_tag); | ||
} | ||
break; | ||
} | ||
} | ||
return vrbe; | ||
} | ||
|
||
gnrc_sixlowpan_frag_vrb_t *gnrc_sixlowpan_frag_vrb_get( | ||
const uint8_t *src, size_t src_len, | ||
const uint8_t *dst, size_t dst_len, | ||
size_t datagram_size, unsigned src_tag) | ||
{ | ||
DEBUG("6lo vrb: trying to get entry for (%s, ", | ||
gnrc_netif_addr_to_str(src, src_len, l2addr_str)); | ||
DEBUG("%s, %u, %u)\n", | ||
gnrc_netif_addr_to_str(dst, dst_len, l2addr_str), | ||
(unsigned)datagram_size, src_tag); | ||
for (unsigned i = 0; i < GNRC_SIXLOWPAN_FRAG_VRB_SIZE; i++) { | ||
gnrc_sixlowpan_frag_vrb_t *vrbe = &_vrb[i]; | ||
|
||
if ((vrbe->super.datagram_size == datagram_size) && | ||
(vrbe->super.tag == src_tag) && | ||
(vrbe->super.src_len == src_len) && | ||
(vrbe->super.dst_len == dst_len) && | ||
(memcmp(vrbe->super.src, src, src_len) == 0) && | ||
(memcmp(vrbe->super.dst, dst, dst_len) == 0)) { | ||
DEBUG("6lo vrb: got VRB to (%s, %u)\n", | ||
gnrc_netif_addr_to_str(vrbe->out_dst, | ||
vrbe->out_dst_len, | ||
l2addr_str), vrbe->out_tag); | ||
return vrbe; | ||
} | ||
} | ||
DEBUG("6lo vrb: no entry found\n"); | ||
return NULL; | ||
} | ||
|
||
void gnrc_sixlowpan_frag_vrb_gc(void) | ||
{ | ||
uint32_t now_usec = xtimer_now_usec(); | ||
|
||
for (unsigned i = 0; i < GNRC_SIXLOWPAN_FRAG_VRB_SIZE; i++) { | ||
if (!gnrc_sixlowpan_frag_vrb_entry_empty(&_vrb[i]) && | ||
(now_usec - _vrb[i].super.arrival) > GNRC_SIXLOWPAN_FRAG_VRB_TIMEOUT_US) { | ||
DEBUG("6lo vrb: entry (%s, ", | ||
gnrc_netif_addr_to_str(_vrb[i].super.src, | ||
_vrb[i].super.src_len, | ||
l2addr_str)); | ||
DEBUG("%s, %u, %u) timed out\n", | ||
gnrc_netif_addr_to_str(_vrb[i].super.dst, | ||
_vrb[i].super.dst_len, | ||
l2addr_str), | ||
(unsigned)_vrb[i].super.datagram_size, _vrb[i].super.tag); | ||
gnrc_sixlowpan_frag_vrb_rm(&_vrb[i]); | ||
} | ||
} | ||
} | ||
|
||
#ifdef TEST_SUITES | ||
void gnrc_sixlowpan_frag_vrb_reset(void) | ||
{ | ||
memset(_vrb, 0, sizeof(_vrb)); | ||
} | ||
#endif | ||
|
||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
include $(RIOTBASE)/Makefile.base |
2 changes: 2 additions & 0 deletions
2
tests/unittests/tests-gnrc_sixlowpan_frag_vrb/Makefile.include
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
USEMODULE += gnrc_sixlowpan_frag_vrb | ||
USEMODULE += xtimer |
Oops, something went wrong.