Merge pull request #11000 from miri64/gnrc_sixlowpan_frag/new/vrb
gnrc_sixlowpan_frag: initial import of the VRB
This commit is contained in:
commit
02df6ab13f
@ -115,6 +115,37 @@ extern "C" {
|
||||
#define GNRC_SIXLOWPAN_ND_AR_LTIME (15U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Size of the virtual reassembly buffer
|
||||
*
|
||||
* @see https://tools.ietf.org/html/draft-ietf-lwig-6lowpan-virtual-reassembly-01
|
||||
*
|
||||
* @note Only applicable with
|
||||
* [gnrc_sixlowpan_frag_vrb](@ref net_gnrc_sixlowpan_frag_vrb) module,
|
||||
* but has also a direct influence on the number of available
|
||||
* gnrc_sixlowpan_rbuf_int_t entries (even when
|
||||
* `gnrc_sixlowpan_frag_vrb` is not compiled in).
|
||||
*/
|
||||
#ifndef GNRC_SIXLOWPAN_FRAG_VRB_SIZE
|
||||
#if defined(MODULE_GNRC_SIXLOWPAN_FRAG_VRB) || defined(DOXYGEN)
|
||||
#define GNRC_SIXLOWPAN_FRAG_VRB_SIZE (16U)
|
||||
#else /* defined(MODULE_GNRC_SIXLOWPAN_FRAG_VRB) || defined(DOXYGEN) */
|
||||
#define GNRC_SIXLOWPAN_FRAG_VRB_SIZE (0U)
|
||||
#endif /* defined(MODULE_GNRC_SIXLOWPAN_FRAG_VRB) || defined(DOXYGEN) */
|
||||
#endif /* GNRC_SIXLOWPAN_FRAG_VRB_SIZE */
|
||||
|
||||
/**
|
||||
* @brief Timeout for a VRB entry in microseconds
|
||||
*
|
||||
* @see https://tools.ietf.org/html/draft-ietf-lwig-6lowpan-virtual-reassembly-01
|
||||
*
|
||||
* @note Only applicable with
|
||||
* [gnrc_sixlowpan_frag_vrb](@ref net_gnrc_sixlowpan_frag_vrb) module.
|
||||
*/
|
||||
#ifndef GNRC_SIXLOWPAN_FRAG_VRB_TIMEOUT_US
|
||||
#define GNRC_SIXLOWPAN_FRAG_VRB_TIMEOUT_US (GNRC_SIXLOWPAN_FRAG_RBUF_TIMEOUT_US)
|
||||
#endif /* GNRC_SIXLOWPAN_FRAG_VRB_TIMEOUT_US */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
149
sys/include/net/gnrc/sixlowpan/frag/vrb.h
Normal file
149
sys/include/net/gnrc/sixlowpan/frag/vrb.h
Normal file
@ -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 <m.lenders@fu-berlin.de>
|
||||
*/
|
||||
#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 */
|
||||
/** @} */
|
||||
@ -88,6 +88,9 @@ endif
|
||||
ifneq (,$(filter gnrc_sixlowpan_frag,$(USEMODULE)))
|
||||
DIRS += network_layer/sixlowpan/frag
|
||||
endif
|
||||
ifneq (,$(filter gnrc_sixlowpan_frag_vrb,$(USEMODULE)))
|
||||
DIRS += network_layer/sixlowpan/frag/vrb
|
||||
endif
|
||||
ifneq (,$(filter gnrc_sixlowpan_iphc,$(USEMODULE)))
|
||||
DIRS += network_layer/sixlowpan/iphc
|
||||
endif
|
||||
|
||||
@ -394,7 +394,7 @@ void gnrc_sixlowpan_frag_rbuf_dispatch_when_complete(gnrc_sixlowpan_rbuf_t *rbuf
|
||||
{
|
||||
assert(rbuf);
|
||||
assert(netif_hdr);
|
||||
if (rbuf->super.current_size == rbuf->pkt->size) {
|
||||
if (rbuf->super.current_size == rbuf->super.datagram_size) {
|
||||
gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(rbuf->super.src,
|
||||
rbuf->super.src_len,
|
||||
rbuf->super.dst,
|
||||
|
||||
@ -21,6 +21,9 @@
|
||||
#include "net/gnrc.h"
|
||||
#include "net/gnrc/sixlowpan.h"
|
||||
#include "net/gnrc/sixlowpan/frag.h"
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_VRB
|
||||
#include "net/gnrc/sixlowpan/frag/vrb.h"
|
||||
#endif /* MODULE_GNRC_SIXLOWPAN_FRAG_VRB */
|
||||
#include "net/sixlowpan.h"
|
||||
#include "thread.h"
|
||||
#include "xtimer.h"
|
||||
@ -264,7 +267,7 @@ void rbuf_gc(void)
|
||||
|
||||
for (i = 0; i < RBUF_SIZE; i++) {
|
||||
/* since pkt occupies pktbuf, aggressivly collect garbage */
|
||||
if ((rbuf[i].pkt != NULL) &&
|
||||
if (!rbuf_entry_empty(&rbuf[i]) &&
|
||||
((now_usec - rbuf[i].super.arrival) > RBUF_TIMEOUT)) {
|
||||
DEBUG("6lo rfrag: entry (%s, ",
|
||||
gnrc_netif_addr_to_str(rbuf[i].super.src,
|
||||
@ -280,6 +283,9 @@ void rbuf_gc(void)
|
||||
rbuf_rm(&(rbuf[i]));
|
||||
}
|
||||
}
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_VRB
|
||||
gnrc_sixlowpan_frag_vrb_gc();
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void _set_rbuf_timeout(void)
|
||||
|
||||
3
sys/net/gnrc/network_layer/sixlowpan/frag/vrb/Makefile
Normal file
3
sys/net/gnrc/network_layer/sixlowpan/frag/vrb/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE := gnrc_sixlowpan_frag_vrb
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
@ -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 <m.lenders@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#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
|
||||
|
||||
/** @} */
|
||||
1
tests/unittests/tests-gnrc_sixlowpan_frag_vrb/Makefile
Normal file
1
tests/unittests/tests-gnrc_sixlowpan_frag_vrb/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
@ -0,0 +1,2 @@
|
||||
USEMODULE += gnrc_sixlowpan_frag_vrb
|
||||
USEMODULE += xtimer
|
||||
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||
* @file
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "embUnit/embUnit.h"
|
||||
|
||||
#include "net/gnrc/sixlowpan/frag/vrb.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#include "tests-gnrc_sixlowpan_frag_vrb.h"
|
||||
|
||||
#define TEST_TAG_INITIAL (6U)
|
||||
#define TEST_SRC { 0x68, 0xDF, 0x2A, 0x5B, 0x21, 0x7D, 0xEE, 0xE5 }
|
||||
#define TEST_DST { 0xB1, 0x5B, 0x0F, 0x2F, 0x63, 0x76, 0x28, 0x39 }
|
||||
#define TEST_OUT_DST { 0x13, 0xF8, 0xEB, 0x75, 0x46, 0x60, 0x7C, 0x60 }
|
||||
#define TEST_SRC_LEN (8U)
|
||||
#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;
|
||||
|
||||
static void set_up(void)
|
||||
{
|
||||
gnrc_sixlowpan_frag_vrb_reset();
|
||||
tag = 0;
|
||||
}
|
||||
|
||||
static void test_vrb_add__success(void)
|
||||
{
|
||||
static const gnrc_sixlowpan_rbuf_int_t interval = {
|
||||
.next = NULL,
|
||||
.start = 0,
|
||||
.end = 116U,
|
||||
};
|
||||
static const gnrc_sixlowpan_rbuf_base_t base = {
|
||||
.ints = (gnrc_sixlowpan_rbuf_int_t *)&interval,
|
||||
.src = TEST_SRC,
|
||||
.dst = TEST_DST,
|
||||
.src_len = TEST_SRC_LEN,
|
||||
.dst_len = TEST_DST_LEN,
|
||||
.tag = TEST_TAG,
|
||||
.datagram_size = 1156U,
|
||||
.current_size = 116U,
|
||||
.arrival = 1742197326U,
|
||||
};
|
||||
static uint8_t out_dst[] = TEST_OUT_DST;
|
||||
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,
|
||||
sizeof(out_dst))));
|
||||
TEST_ASSERT_NOT_NULL(res->super.ints);
|
||||
TEST_ASSERT_NULL(res->super.ints->next);
|
||||
/* make sure base and res->super are distinct*/
|
||||
TEST_ASSERT((&base) != (&res->super));
|
||||
/* but that the values are the same */
|
||||
TEST_ASSERT_EQUAL_INT(interval.start, res->super.ints->start);
|
||||
TEST_ASSERT_EQUAL_INT(interval.end, res->super.ints->end);
|
||||
TEST_ASSERT_EQUAL_INT(base.src_len, res->super.src_len);
|
||||
TEST_ASSERT_MESSAGE(memcmp(base.src, res->super.src, TEST_SRC_LEN) == 0,
|
||||
"TEST_SRC != res->super.src");
|
||||
TEST_ASSERT_EQUAL_INT(base.dst_len, res->super.src_len);
|
||||
TEST_ASSERT_MESSAGE(memcmp(base.dst, res->super.dst, TEST_DST_LEN) == 0,
|
||||
"TEST_DST != res->super.dst");
|
||||
TEST_ASSERT_EQUAL_INT(base.tag, res->super.tag);
|
||||
TEST_ASSERT_EQUAL_INT(base.datagram_size, res->super.datagram_size);
|
||||
TEST_ASSERT_EQUAL_INT(base.current_size, res->super.current_size);
|
||||
TEST_ASSERT_EQUAL_INT(base.arrival, res->super.arrival);
|
||||
TEST_ASSERT((&_dummy_netif) == res->out_netif);
|
||||
TEST_ASSERT_EQUAL_INT(sizeof(out_dst), res->out_dst_len);
|
||||
TEST_ASSERT_MESSAGE(memcmp(out_dst, res->out_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)
|
||||
{
|
||||
static const gnrc_sixlowpan_rbuf_int_t interval = {
|
||||
.next = NULL,
|
||||
.start = 0,
|
||||
.end = 116U,
|
||||
};
|
||||
static const gnrc_sixlowpan_rbuf_base_t base = {
|
||||
.ints = (gnrc_sixlowpan_rbuf_int_t *)&interval,
|
||||
.src = TEST_SRC,
|
||||
.dst = TEST_DST,
|
||||
.src_len = TEST_SRC_LEN,
|
||||
.dst_len = TEST_DST_LEN,
|
||||
.tag = TEST_TAG,
|
||||
.datagram_size = 1156U,
|
||||
.current_size = 116U,
|
||||
.arrival = 1742197326U,
|
||||
};
|
||||
static uint8_t out_dst[] = TEST_OUT_DST;
|
||||
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,
|
||||
sizeof(out_dst))));
|
||||
TEST_ASSERT_NOT_NULL((res2 = gnrc_sixlowpan_frag_vrb_add(&base,
|
||||
&_dummy_netif,
|
||||
out_dst,
|
||||
sizeof(out_dst))));
|
||||
TEST_ASSERT(res1 == res2);
|
||||
}
|
||||
|
||||
static void test_vrb_add__full(void)
|
||||
{
|
||||
gnrc_sixlowpan_rbuf_base_t base = {
|
||||
.ints = NULL,
|
||||
.src = TEST_SRC,
|
||||
.dst = TEST_DST,
|
||||
.src_len = TEST_SRC_LEN,
|
||||
.dst_len = TEST_DST_LEN,
|
||||
.tag = TEST_TAG,
|
||||
.datagram_size = 1156U,
|
||||
.current_size = 116U,
|
||||
.arrival = 1742197326U,
|
||||
};
|
||||
static uint8_t out_dst[] = TEST_OUT_DST;
|
||||
|
||||
/* fill up VRB */
|
||||
for (unsigned i = 0; i < GNRC_SIXLOWPAN_FRAG_VRB_SIZE; i++) {
|
||||
TEST_ASSERT_NOT_NULL(gnrc_sixlowpan_frag_vrb_add(&base,
|
||||
&_dummy_netif,
|
||||
out_dst,
|
||||
sizeof(out_dst)));
|
||||
base.tag++;
|
||||
}
|
||||
/* another entry will not fit */
|
||||
TEST_ASSERT_NULL(gnrc_sixlowpan_frag_vrb_add(&base, &_dummy_netif,
|
||||
out_dst, sizeof(out_dst)));
|
||||
/* check if it really isn't in the VRB */
|
||||
TEST_ASSERT_NULL(gnrc_sixlowpan_frag_vrb_get(base.src, base.src_len,
|
||||
base.dst, base.dst_len,
|
||||
base.datagram_size, base.tag));
|
||||
}
|
||||
|
||||
static void test_vrb_get__empty(void)
|
||||
{
|
||||
static const gnrc_sixlowpan_rbuf_base_t base = {
|
||||
.ints = NULL,
|
||||
.src = TEST_SRC,
|
||||
.dst = TEST_DST,
|
||||
.src_len = TEST_SRC_LEN,
|
||||
.dst_len = TEST_DST_LEN,
|
||||
.tag = TEST_TAG,
|
||||
.datagram_size = 1156U,
|
||||
.current_size = 116U,
|
||||
.arrival = 1742197326U,
|
||||
};
|
||||
TEST_ASSERT_NULL(gnrc_sixlowpan_frag_vrb_get(base.src, base.src_len,
|
||||
base.dst, base.dst_len,
|
||||
base.datagram_size, base.tag));
|
||||
}
|
||||
|
||||
static void test_vrb_get__after_add(void)
|
||||
{
|
||||
static const gnrc_sixlowpan_rbuf_base_t base = {
|
||||
.ints = NULL,
|
||||
.src = TEST_SRC,
|
||||
.dst = TEST_DST,
|
||||
.src_len = TEST_SRC_LEN,
|
||||
.dst_len = TEST_DST_LEN,
|
||||
.tag = TEST_TAG,
|
||||
.datagram_size = 1156U,
|
||||
.current_size = 116U,
|
||||
.arrival = 1742197326U,
|
||||
};
|
||||
static uint8_t out_dst[] = TEST_OUT_DST;
|
||||
gnrc_sixlowpan_frag_vrb_t *res1, *res2;
|
||||
|
||||
TEST_ASSERT_NOT_NULL((res1 = gnrc_sixlowpan_frag_vrb_add(&base,
|
||||
&_dummy_netif,
|
||||
out_dst,
|
||||
sizeof(out_dst))));
|
||||
TEST_ASSERT_NOT_NULL((res2 = gnrc_sixlowpan_frag_vrb_get(base.src,
|
||||
base.src_len,
|
||||
base.dst,
|
||||
base.dst_len,
|
||||
base.datagram_size,
|
||||
base.tag)));
|
||||
TEST_ASSERT(res1 == res2);
|
||||
}
|
||||
|
||||
static void test_vrb_rm(void)
|
||||
{
|
||||
static const gnrc_sixlowpan_rbuf_base_t base = {
|
||||
.ints = NULL,
|
||||
.src = TEST_SRC,
|
||||
.dst = TEST_DST,
|
||||
.src_len = TEST_SRC_LEN,
|
||||
.dst_len = TEST_DST_LEN,
|
||||
.tag = TEST_TAG,
|
||||
.datagram_size = 1156U,
|
||||
.current_size = 116U,
|
||||
.arrival = 1742197326U,
|
||||
};
|
||||
static uint8_t out_dst[] = TEST_OUT_DST;
|
||||
gnrc_sixlowpan_frag_vrb_t *res;
|
||||
|
||||
TEST_ASSERT_NOT_NULL((res = gnrc_sixlowpan_frag_vrb_add(&base,
|
||||
&_dummy_netif,
|
||||
out_dst,
|
||||
sizeof(out_dst))));
|
||||
gnrc_sixlowpan_frag_vrb_rm(res);
|
||||
TEST_ASSERT_NULL(gnrc_sixlowpan_frag_vrb_get(base.src, base.src_len,
|
||||
base.dst, base.dst_len,
|
||||
base.datagram_size, base.tag));
|
||||
}
|
||||
|
||||
static void test_vrb_gc(void)
|
||||
{
|
||||
gnrc_sixlowpan_rbuf_base_t base = {
|
||||
.ints = NULL,
|
||||
.src = TEST_SRC,
|
||||
.dst = TEST_DST,
|
||||
.src_len = TEST_SRC_LEN,
|
||||
.dst_len = TEST_DST_LEN,
|
||||
.tag = TEST_TAG,
|
||||
.datagram_size = 1156U,
|
||||
.current_size = 116U,
|
||||
.arrival = xtimer_now_usec() - GNRC_SIXLOWPAN_FRAG_VRB_TIMEOUT_US - 1000,
|
||||
};
|
||||
static uint8_t out_dst[] = TEST_OUT_DST;
|
||||
gnrc_sixlowpan_frag_vrb_t *res;
|
||||
|
||||
TEST_ASSERT_NOT_NULL((res = gnrc_sixlowpan_frag_vrb_add(&base,
|
||||
&_dummy_netif,
|
||||
out_dst,
|
||||
sizeof(out_dst))));
|
||||
gnrc_sixlowpan_frag_vrb_gc();
|
||||
TEST_ASSERT_NULL(gnrc_sixlowpan_frag_vrb_get(base.src, base.src_len,
|
||||
base.dst, base.dst_len,
|
||||
base.datagram_size, base.tag));
|
||||
}
|
||||
|
||||
static Test *tests_gnrc_sixlowpan_frag_vrb_tests(void)
|
||||
{
|
||||
EMB_UNIT_TESTFIXTURES(fixtures) {
|
||||
new_TestFixture(test_vrb_add__success),
|
||||
new_TestFixture(test_vrb_add__duplicate),
|
||||
new_TestFixture(test_vrb_add__full),
|
||||
new_TestFixture(test_vrb_get__empty),
|
||||
new_TestFixture(test_vrb_get__after_add),
|
||||
new_TestFixture(test_vrb_rm),
|
||||
new_TestFixture(test_vrb_gc),
|
||||
};
|
||||
|
||||
EMB_UNIT_TESTCALLER(vrb_tests, set_up, NULL, fixtures);
|
||||
|
||||
return (Test *)&vrb_tests;
|
||||
}
|
||||
|
||||
void tests_gnrc_sixlowpan_frag_vrb(void)
|
||||
{
|
||||
xtimer_init();
|
||||
TESTS_RUN(tests_gnrc_sixlowpan_frag_vrb_tests());
|
||||
}
|
||||
/** @} */
|
||||
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup unittests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Unittests for the `gnrc_sixlowpan_frag_vrb` module
|
||||
*
|
||||
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||
*/
|
||||
#ifndef TESTS_GNRC_SIXLOWPAN_FRAG_VRB_H
|
||||
#define TESTS_GNRC_SIXLOWPAN_FRAG_VRB_H
|
||||
|
||||
#include "embUnit.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The entry point of this test suite.
|
||||
*/
|
||||
void tests_gnrc_sixlowpan_frag_vrb(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TESTS_GNRC_SIXLOWPAN_FRAG_VRB_H */
|
||||
/** @} */
|
||||
Loading…
x
Reference in New Issue
Block a user