1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #12303 from miri64/sixlowpan_sfr/feat/initial

sixlowpan_sfr: initial import Selective Fragment Recovery definitions
This commit is contained in:
Martine Lenders 2019-10-01 09:46:25 +02:00 committed by GitHub
commit f4cca412de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 663 additions and 0 deletions

View File

@ -61,6 +61,27 @@ extern "C" {
*/
#define SIXLOWPAN_IPHC1_DISP (0x60)
/**
* @brief Dispatch mask for 6LoWPAN selective fragment recovery
* @see [draft-ietf-6lo-fragment-recovery-05,
* section 5](https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-05#section-5)
*/
#define SIXLOWPAN_SFR_DISP_MASK (0xfe)
/**
* @brief Dispatch for 6LoWPAN recoverable fragment
* @see [draft-ietf-6lo-fragment-recovery-05, section
* 5.1](https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-05#section-5.1)
*/
#define SIXLOWPAN_SFR_RFRAG_DISP (0xe8)
/**
* @brief Dispatch for 6LoWPAN recoverable fragment acknowledgment
* @see [draft-ietf-6lo-fragment-recovery-05, section
* 5.2](https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-05#section-5.2)
*/
#define SIXLOWPAN_SFR_ACK_DISP (0xea)
/**
* @brief Checks if dispatch indicates that frame is not a 6LoWPAN (NALP) frame.
*

View File

@ -0,0 +1,381 @@
/*
* 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_sixlowpan_sfr 6LoWPAN selective fragment recovery
* @ingroup net_sixlowpan
* @brief Provides dispatches for 6LoWPAN selective fragment recovery and
* helper functions
* @{
*
* @file
* @brief 6LoWPAN selective fragment recovery dispatch type and helper
* function definitions.
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NET_SIXLOWPAN_SFR_H
#define NET_SIXLOWPAN_SFR_H
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include "bitfield.h"
#include "byteorder.h"
#include "net/sixlowpan.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Mask for generic dispatch of both selective fragment recovery
* headers
*
* @see SIXLOWPAN_SFR_GEN_DISP
* @see SIXLOWPAN_SFR_DISP_MASK
* @see SIXLOWPAN_SFR_RFRAG_DISP
* @see SIXLOWPAN_SFR_ACK_DISP
*/
#define SIXLOWPAN_SFR_GEN_DISP_MASK (0xfc)
#define SIXLOWPAN_SFR_GEN_DISP (0xe8) /**< generic dispatch for both SFR headers */
#define SIXLOWPAN_SFR_ECN (0x01U) /**< explicit congestion notification flag */
#define SIXLOWPAN_SFR_ACK_REQ (0x80U) /**< Acknowledgment request flag (for 8 MSB) */
#define SIXLOWPAN_SFR_SEQ_MASK (0x7cU) /**< Sequence number mask (for 8 MSB) */
#define SIXLOWPAN_SFR_SEQ_POS (2U) /**< Sequence number position (for 8 MSB) */
#define SIXLOWPAN_SFR_SEQ_MAX (0x1fU) /**< Maximum value for sequence number */
#define SIXLOWPAN_SFR_FRAG_SIZE_MASK (0x03ffU) /**< Fragment size mask */
#define SIXLOWPAN_SFR_FRAG_SIZE_MAX (0x03ffU) /**< Maximum value for fragment size */
#define SIXLOWPAN_SFR_ACK_BITMAP_SIZE (32U) /**< Acknowledgment bitmap size in bits */
/**
* @brief Generic type for selective fragment recovery headers
*
* @see [draft-ietf-6lo-fragment-recovery-05, section
* 5](https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-05#section-5)
*/
typedef struct __attribute__((packed)) {
/**
* @brief Dispatch and explicit congestion notification (ECN) flag
*
* In network byte-order the 7 most significant bits are the dispatch (7
* bits) and the least significant bit is the ECN flag:
*
* +-+-+-+-+-+-+-+-+
* | Dispatch |E|
* +-+-+-+-+-+-+-+-+
*
* For @ref sixlowpan_sfr_ack_t the ECN flag represents the ECN echo flag.
*
* This module provides helper functions to set, get, check these fields
* accordingly:
*
* - sixlowpan_sfr_is()
* - sixlowpan_sfr_set_ecn()
* - sixlowpan_sfr_clear_ecn()
* - sixlowpan_sfr_ecn()
* - sixlowpan_sfr_rfrag_set_disp()
* - sixlowpan_sfr_rfrag_is()
* - sixlowpan_sfr_ack_set_disp()
* - sixlowpan_sfr_ack_is()
*/
uint8_t disp_ecn;
uint8_t tag; /**< Datagram tag */
} sixlowpan_sfr_t;
/**
* @brief Recoverable fragment header
*
* @see [draft-ietf-6lo-fragment-recovery-05, section
* 5.1](https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-05#section-5.1)
*/
typedef struct __attribute__((packed)) {
sixlowpan_sfr_t base; /**< generic part */
/**
* @brief Acknowledgment request flag, sequence number, and fragment size
*
* In network byte-order the most significant bit is the acknowledgment
* request flag, the second to sixth most significant bits are the sequence
* number (5 bits), and the 10 least significant bits are the fragment size
* (10 bits):
*
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |X| sequence| fragment_size |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* This module provides helper functions to set, get, check these fields
* accordingly:
*
* - sixlowpan_sfr_rfrag_set_ack_req()
* - sixlowpan_sfr_rfrag_clear_ack_req()
* - sixlowpan_sfr_rfrag_ack_req()
* - sixlowpan_sfr_rfrag_set_seq()
* - sixlowpan_sfr_rfrag_get_seq()
* - sixlowpan_sfr_rfrag_set_frag_size()
* - sixlowpan_sfr_rfrag_get_frag_size()
*/
network_uint16_t ar_seq_fs;
/**
* @brief Fragment offset
*
* This module provides helper functions to set, get, check these fields
* accordingly:
*
* - sixlowpan_sfr_rfrag_set_offset()
* - sixlowpan_sfr_rfrag_get_offset()
*/
network_uint16_t offset;
} sixlowpan_sfr_rfrag_t;
/**
* @brief Recoverable fragment (RFRAG) acknowledgment header
*
* @see [draft-ietf-6lo-fragment-recovery-05, section
* 5.2](https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-05#section-5.2)
*/
typedef struct __attribute__((packed)) {
sixlowpan_sfr_t base; /**< generic part */
/**
* @brief RFRAG acknowledgment bitmap
*/
BITFIELD(bitmap, SIXLOWPAN_SFR_ACK_BITMAP_SIZE);
} sixlowpan_sfr_ack_t;
/**
* @brief Check if given header is a 6LoWPAN selective fragment recovery
* header (either RFRAG or RFRAG ACK)
*
* @see @ref SIXLOWPAN_SFR_RFRAG_DISP
*
* @param[in] hdr The 6LoWPAN selective fragment recovery header to check
*
* return true, if @p hdr is a 6LoWPAN selective fragment recovery header
* return false, if @p hdr is not a 6LoWPAN selective fragment recovery header
*/
static inline bool sixlowpan_sfr_is(sixlowpan_sfr_t *hdr)
{
return ((hdr->disp_ecn & SIXLOWPAN_SFR_GEN_DISP_MASK) == SIXLOWPAN_SFR_GEN_DISP);
}
/**
* @brief Set the ECN flag in a 6LoWPAN selective fragment recovery header
*
* @param[in,out] hdr A 6LoWPAN selective fragment recovery header
*/
static inline void sixlowpan_sfr_set_ecn(sixlowpan_sfr_t *hdr)
{
hdr->disp_ecn |= SIXLOWPAN_SFR_ECN;
}
/**
* @brief Clear the ECN flag in a 6LoWPAN recoverable fragment header
*
* @param[in,out] hdr A 6LoWPAN selective fragment recovery header
*/
static inline void sixlowpan_sfr_clear_ecn(sixlowpan_sfr_t *hdr)
{
hdr->disp_ecn &= ~SIXLOWPAN_SFR_ECN;
}
/**
* @brief Check if the ECN flag in a 6LoWPAN recoverable fragment header is
* set
*
* @param[in] hdr A 6LoWPAN selective fragment recovery header
*
* return true, if ECN flag in @p hdr is set
* return false, if ECN flag in @p hdr is cleared
*/
static inline bool sixlowpan_sfr_ecn(const sixlowpan_sfr_t *hdr)
{
return (hdr->disp_ecn & SIXLOWPAN_SFR_ECN);
}
/**
* @brief Initialize 6LoWPAN recoverable fragment dispatch
*
* @see @ref SIXLOWPAN_SFR_RFRAG_DISP
*
* @param[in,out] hdr A 6LoWPAN selective fragment recovery header
*/
static inline void sixlowpan_sfr_rfrag_set_disp(sixlowpan_sfr_t *hdr)
{
hdr->disp_ecn &= ~SIXLOWPAN_SFR_DISP_MASK;
hdr->disp_ecn |= SIXLOWPAN_SFR_RFRAG_DISP;
}
/**
* @brief Check if given header is a 6LoWPAN recoverable fragment header
*
* @see @ref SIXLOWPAN_SFR_RFRAG_DISP
*
* @param[in] hdr The 6LoWPAN selective fragment recovery header to check
*
* return true, if @p hdr is a 6LoWPAN recoverable fragment header
* return false, if @p hdr is not a 6LoWPAN recoverable fragment header
*/
static inline bool sixlowpan_sfr_rfrag_is(const sixlowpan_sfr_t *hdr)
{
return ((hdr->disp_ecn & SIXLOWPAN_SFR_DISP_MASK) == SIXLOWPAN_SFR_RFRAG_DISP);
}
/**
* @brief Set the Acknowledgment request flag in a 6LoWPAN recoverable
* fragment header
*
* @param[in,out] hdr A 6LoWPAN recoverable fragment header
*/
static inline void sixlowpan_sfr_rfrag_set_ack_req(sixlowpan_sfr_rfrag_t *hdr)
{
hdr->ar_seq_fs.u8[0] |= SIXLOWPAN_SFR_ACK_REQ;
}
/**
* @brief Clear the Acknowledgment request flag in a 6LoWPAN recoverable
* fragment header
*
* @param[in,out] hdr A 6LoWPAN recoverable fragment header
*/
static inline void sixlowpan_sfr_rfrag_clear_ack_req(sixlowpan_sfr_rfrag_t *hdr)
{
hdr->ar_seq_fs.u8[0] &= ~SIXLOWPAN_SFR_ACK_REQ;
}
/**
* @brief Check if the Acknowledgment request flag in a 6LoWPAN recoverable
* fragment header is set
*
* @param[in] hdr A 6LoWPAN recoverable fragment header
*
* return true, if Acknowledgment request flag in @p hdr is set
* return false, if Acknowledgment request flag in @p hdr is cleared
*/
static inline bool sixlowpan_sfr_rfrag_ack_req(sixlowpan_sfr_rfrag_t *hdr)
{
return (hdr->ar_seq_fs.u8[0] & SIXLOWPAN_SFR_ACK_REQ);
}
/**
* @brief Set sequence number in a 6LoWPAN recoverable fragment header
*
* @pre `seq <= SIXLOWPAN_SFR_SEQ_MAX`
*
* @param[in,out] hdr A 6LoWPAN recoverable fragment header
* @param[in] seq The sequence number to set. Must be lesser or equal
* to @ref SIXLOWPAN_SFR_SEQ_MAX.
*/
static inline void sixlowpan_sfr_rfrag_set_seq(sixlowpan_sfr_rfrag_t *hdr,
uint8_t seq)
{
assert(seq <= SIXLOWPAN_SFR_SEQ_MAX);
hdr->ar_seq_fs.u8[0] &= ~SIXLOWPAN_SFR_SEQ_MASK;
hdr->ar_seq_fs.u8[0] |= (seq << SIXLOWPAN_SFR_SEQ_POS);
}
/**
* @brief Get sequence number from a 6LoWPAN recoverable fragment header
*
* @param[in] hdr A 6LoWPAN recoverable fragment header
*
* @return The sequence number of the 6LoWPAN recoverable fragment
*/
static inline uint8_t sixlowpan_sfr_rfrag_get_seq(const sixlowpan_sfr_rfrag_t *hdr)
{
return ((hdr->ar_seq_fs.u8[0] & SIXLOWPAN_SFR_SEQ_MASK) >>
SIXLOWPAN_SFR_SEQ_POS);
}
/**
* @brief Set fragment size in a 6LoWPAN recoverable fragment header
*
* @pre `frag_size <= SIXLOWPAN_SFR_FRAG_SIZE_MAX`
*
* @param[in,out] hdr A 6LoWPAN recoverable fragment header
* @param[in] frag_size The fragment size to set. Must be lesser or equal to
* @ref SIXLOWPAN_SFR_FRAG_SIZE_MAX.
*/
static inline void sixlowpan_sfr_rfrag_set_frag_size(sixlowpan_sfr_rfrag_t *hdr,
uint16_t frag_size)
{
assert(frag_size <= SIXLOWPAN_SFR_FRAG_SIZE_MAX);
hdr->ar_seq_fs.u16 &= ~htons(SIXLOWPAN_SFR_FRAG_SIZE_MASK);
hdr->ar_seq_fs.u16 |= htons(frag_size);
}
/**
* @brief Get fragment size from a 6LoWPAN recoverable fragment header
*
* @param[in] hdr A 6LoWPAN recoverable fragment header
*
* @return The fragment size of the 6LoWPAN recoverable fragment
*/
static inline uint16_t sixlowpan_sfr_rfrag_get_frag_size(const sixlowpan_sfr_rfrag_t *hdr)
{
return (byteorder_ntohs(hdr->ar_seq_fs) & SIXLOWPAN_SFR_FRAG_SIZE_MASK);
}
/**
* @brief Set fragment offset in a 6LoWPAN recoverable fragment header
*
* @param[in,out] hdr A 6LoWPAN recoverable fragment header
* @param[in] offset The fragment offset to set.
*/
static inline void sixlowpan_sfr_rfrag_set_offset(sixlowpan_sfr_rfrag_t *hdr,
uint16_t offset)
{
hdr->offset = byteorder_htons(offset);
}
/**
* @brief Get fragment offset from a 6LoWPAN recoverable fragment header
*
* @param[in] hdr A 6LoWPAN recoverable fragment header
*
* @return The fragment offset of the 6LoWPAN recoverable fragment
*/
static inline uint16_t sixlowpan_sfr_rfrag_get_offset(const sixlowpan_sfr_rfrag_t *hdr)
{
return byteorder_ntohs(hdr->offset);
}
/**
* @brief Initialize 6LoWPAN RFRAG acknowledgment dispatch
*
* @see @ref SIXLOWPAN_SFR_ACK_DISP
*
* @param[in,out] hdr A 6LoWPAN selective fragment recovery header
*/
static inline void sixlowpan_sfr_ack_set_disp(sixlowpan_sfr_t *hdr)
{
hdr->disp_ecn &= ~SIXLOWPAN_SFR_DISP_MASK;
hdr->disp_ecn |= SIXLOWPAN_SFR_ACK_DISP;
}
/**
* @brief Check if given header is a 6LoWPAN RFRAG acknowledgment header
*
* @see @ref SIXLOWPAN_SFR_ACK_DISP
*
* @param[in] hdr The 6LoWPAN selective fragment recovery header to check
*
* return true, if @p hdr is a 6LoWPAN RFRAG acknowledgment header
* return false, if @p hdr is not a 6LoWPAN RFRAG acknowledgment header
*/
static inline bool sixlowpan_sfr_ack_is(const sixlowpan_sfr_t *hdr)
{
return ((hdr->disp_ecn & SIXLOWPAN_SFR_DISP_MASK) == SIXLOWPAN_SFR_ACK_DISP);
}
#ifdef __cplusplus
}
#endif
#endif /* NET_SIXLOWPAN_SFR_H */
/** @} */

View File

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,223 @@
/*
* 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 <string.h>
#include "net/sixlowpan/sfr.h"
#include "tests-sixlowpan_sfr.h"
static void test_sixlowpan_sfr_disp(void)
{
sixlowpan_sfr_t hdr = { .disp_ecn = 0U };
TEST_ASSERT(!sixlowpan_sfr_is(&hdr));
sixlowpan_sfr_rfrag_set_disp(&hdr);
TEST_ASSERT(sixlowpan_sfr_is(&hdr));
hdr.disp_ecn = 0U;
sixlowpan_sfr_ack_set_disp(&hdr);
TEST_ASSERT(sixlowpan_sfr_is(&hdr));
}
static void test_sixlowpan_sfr_ecn(void)
{
/* initialize with canary (but ECN unset) */
sixlowpan_sfr_t hdr = { .disp_ecn = 218U };
/* ECN should not be set */
TEST_ASSERT(!sixlowpan_sfr_ecn(&hdr));
sixlowpan_sfr_set_ecn(&hdr);
TEST_ASSERT(sixlowpan_sfr_ecn(&hdr));
/* check if non-ECN field stays unset */
TEST_ASSERT_EQUAL_INT(218U,
hdr.disp_ecn & ~SIXLOWPAN_SFR_ECN);
sixlowpan_sfr_clear_ecn(&hdr);
TEST_ASSERT(!sixlowpan_sfr_ecn(&hdr));
/* check if non-ECN field stays unset */
TEST_ASSERT_EQUAL_INT(218U,
hdr.disp_ecn & ~SIXLOWPAN_SFR_ECN);
}
static void test_sixlowpan_sfr_rfrag_disp(void)
{
/* initialize with canary bit (but dispatch unset) */
sixlowpan_sfr_t hdr = { .disp_ecn = 1U };
TEST_ASSERT(!sixlowpan_sfr_rfrag_is(&hdr));
sixlowpan_sfr_rfrag_set_disp(&hdr);
TEST_ASSERT(sixlowpan_sfr_rfrag_is(&hdr));
/* check if preset value stays the same */
TEST_ASSERT_EQUAL_INT(1U, hdr.disp_ecn & ~SIXLOWPAN_SFR_DISP_MASK);
/* check if it stays the same when ECN is cleared */
sixlowpan_sfr_clear_ecn(&hdr);
TEST_ASSERT(sixlowpan_sfr_rfrag_is(&hdr));
/* check if it stays the same when ECN is set */
sixlowpan_sfr_set_ecn(&hdr);
TEST_ASSERT(sixlowpan_sfr_rfrag_is(&hdr));
}
static void test_sixlowpan_sfr_rfrag_ack_req(void)
{
/* initialize with canary bit (but ack_req unset) */
sixlowpan_sfr_rfrag_t hdr = { .ar_seq_fs = { .u8 = { 0x74, 0x32 } } };
TEST_ASSERT(!sixlowpan_sfr_rfrag_ack_req(&hdr));
sixlowpan_sfr_rfrag_set_ack_req(&hdr);
TEST_ASSERT(sixlowpan_sfr_rfrag_ack_req(&hdr));
/* check if preset values stay the same */
TEST_ASSERT_EQUAL_INT(0x74, hdr.ar_seq_fs.u8[0] & ~SIXLOWPAN_SFR_ACK_REQ);
TEST_ASSERT_EQUAL_INT(0x32, hdr.ar_seq_fs.u8[1]);
sixlowpan_sfr_rfrag_clear_ack_req(&hdr);
TEST_ASSERT(!sixlowpan_sfr_rfrag_ack_req(&hdr));
/* check if preset values stay the same */
TEST_ASSERT_EQUAL_INT(0x74, hdr.ar_seq_fs.u8[0] & ~SIXLOWPAN_SFR_ACK_REQ);
TEST_ASSERT_EQUAL_INT(0x32, hdr.ar_seq_fs.u8[1]);
}
static void test_sixlowpan_sfr_rfrag_seq(void)
{
/* initialize with canary bit (but seq unset) */
sixlowpan_sfr_rfrag_t hdr = { .ar_seq_fs = { .u8 = { 0x83, 0xaa } } };
TEST_ASSERT_EQUAL_INT(0U, sixlowpan_sfr_rfrag_get_seq(&hdr));
sixlowpan_sfr_rfrag_set_seq(&hdr, SIXLOWPAN_SFR_SEQ_MAX);
TEST_ASSERT_EQUAL_INT(SIXLOWPAN_SFR_SEQ_MAX,
sixlowpan_sfr_rfrag_get_seq(&hdr));
/* check if preset values stay the same */
TEST_ASSERT_EQUAL_INT(0x83, hdr.ar_seq_fs.u8[0] & ~SIXLOWPAN_SFR_SEQ_MASK);
TEST_ASSERT_EQUAL_INT(0xaa, hdr.ar_seq_fs.u8[1]);
sixlowpan_sfr_rfrag_set_seq(&hdr, 19U);
TEST_ASSERT_EQUAL_INT(19U, sixlowpan_sfr_rfrag_get_seq(&hdr));
/* check if preset values stay the same */
TEST_ASSERT_EQUAL_INT(0x83, hdr.ar_seq_fs.u8[0] & ~SIXLOWPAN_SFR_SEQ_MASK);
TEST_ASSERT_EQUAL_INT(0xaa, hdr.ar_seq_fs.u8[1]);
sixlowpan_sfr_rfrag_set_seq(&hdr, 7U);
TEST_ASSERT_EQUAL_INT(7U, sixlowpan_sfr_rfrag_get_seq(&hdr));
/* check if preset values stay the same */
TEST_ASSERT_EQUAL_INT(0x83, hdr.ar_seq_fs.u8[0] & ~SIXLOWPAN_SFR_SEQ_MASK);
TEST_ASSERT_EQUAL_INT(0xaa, hdr.ar_seq_fs.u8[1]);
sixlowpan_sfr_rfrag_set_seq(&hdr, 0U);
TEST_ASSERT_EQUAL_INT(0U, sixlowpan_sfr_rfrag_get_seq(&hdr));
/* check if preset values stay the same */
TEST_ASSERT_EQUAL_INT(0x83, hdr.ar_seq_fs.u8[0] & ~SIXLOWPAN_SFR_SEQ_MASK);
TEST_ASSERT_EQUAL_INT(0xaa, hdr.ar_seq_fs.u8[1]);
}
static void test_sixlowpan_sfr_rfrag_frag_size(void)
{
/* initialize with canary bit (but seq unset) */
sixlowpan_sfr_rfrag_t hdr = { .ar_seq_fs = { .u8 = { 0x6c, 0x00 } } };
TEST_ASSERT_EQUAL_INT(0U, sixlowpan_sfr_rfrag_get_frag_size(&hdr));
sixlowpan_sfr_rfrag_set_frag_size(&hdr, SIXLOWPAN_SFR_FRAG_SIZE_MAX);
TEST_ASSERT_EQUAL_INT(SIXLOWPAN_SFR_FRAG_SIZE_MAX,
sixlowpan_sfr_rfrag_get_frag_size(&hdr));
/* check if preset values stay the same */
TEST_ASSERT_EQUAL_INT(0x6c,
hdr.ar_seq_fs.u8[0] &
(SIXLOWPAN_SFR_ACK_REQ | SIXLOWPAN_SFR_SEQ_MASK));
sixlowpan_sfr_rfrag_set_frag_size(&hdr, 113);
TEST_ASSERT_EQUAL_INT(113U, sixlowpan_sfr_rfrag_get_frag_size(&hdr));
/* check if preset values stay the same */
TEST_ASSERT_EQUAL_INT(0x6c,
hdr.ar_seq_fs.u8[0] &
(SIXLOWPAN_SFR_ACK_REQ | SIXLOWPAN_SFR_SEQ_MASK));
sixlowpan_sfr_rfrag_set_frag_size(&hdr, 964);
TEST_ASSERT_EQUAL_INT(964, sixlowpan_sfr_rfrag_get_frag_size(&hdr));
/* check if preset values stay the same */
TEST_ASSERT_EQUAL_INT(0x6c,
hdr.ar_seq_fs.u8[0] &
(SIXLOWPAN_SFR_ACK_REQ | SIXLOWPAN_SFR_SEQ_MASK));
sixlowpan_sfr_rfrag_set_frag_size(&hdr, 0U);
TEST_ASSERT_EQUAL_INT(0U, sixlowpan_sfr_rfrag_get_frag_size(&hdr));
/* check if preset values stay the same */
TEST_ASSERT_EQUAL_INT(0x6c,
hdr.ar_seq_fs.u8[0] &
(SIXLOWPAN_SFR_ACK_REQ | SIXLOWPAN_SFR_SEQ_MASK));
}
static void test_sixlowpan_sfr_rfrag_offset(void)
{
/* initialize with canary bit (but seq unset) */
sixlowpan_sfr_rfrag_t hdr = { .offset = { .u16 = 0 } };
TEST_ASSERT_EQUAL_INT(0U, sixlowpan_sfr_rfrag_get_offset(&hdr));
sixlowpan_sfr_rfrag_set_offset(&hdr, UINT16_MAX);
TEST_ASSERT_EQUAL_INT(UINT16_MAX, sixlowpan_sfr_rfrag_get_offset(&hdr));
sixlowpan_sfr_rfrag_set_offset(&hdr, 58937U);
TEST_ASSERT_EQUAL_INT(58937U, sixlowpan_sfr_rfrag_get_offset(&hdr));
sixlowpan_sfr_rfrag_set_offset(&hdr, 173U);
TEST_ASSERT_EQUAL_INT(173U, sixlowpan_sfr_rfrag_get_offset(&hdr));
sixlowpan_sfr_rfrag_set_offset(&hdr, 0U);
TEST_ASSERT_EQUAL_INT(0U, sixlowpan_sfr_rfrag_get_offset(&hdr));
}
static void test_sixlowpan_sfr_ack_disp(void)
{
/* initialize with canary bit (but dispatch unset) */
sixlowpan_sfr_t hdr = { .disp_ecn = 1U };
TEST_ASSERT(!sixlowpan_sfr_ack_is(&hdr));
sixlowpan_sfr_ack_set_disp(&hdr);
TEST_ASSERT(sixlowpan_sfr_ack_is(&hdr));
/* check if preset value stays the same */
TEST_ASSERT_EQUAL_INT(1U, hdr.disp_ecn & ~SIXLOWPAN_SFR_DISP_MASK);
/* check if it stays the same when ECN is cleared */
sixlowpan_sfr_clear_ecn(&hdr);
TEST_ASSERT(sixlowpan_sfr_ack_is(&hdr));
/* check if it stays the same when ECN is set */
sixlowpan_sfr_set_ecn(&hdr);
TEST_ASSERT(sixlowpan_sfr_ack_is(&hdr));
}
static Test *tests_sixlowpan_sfr_tests(void)
{
EMB_UNIT_TESTFIXTURES(fixtures) {
new_TestFixture(test_sixlowpan_sfr_disp),
new_TestFixture(test_sixlowpan_sfr_ecn),
new_TestFixture(test_sixlowpan_sfr_rfrag_disp),
new_TestFixture(test_sixlowpan_sfr_rfrag_ack_req),
new_TestFixture(test_sixlowpan_sfr_rfrag_seq),
new_TestFixture(test_sixlowpan_sfr_rfrag_frag_size),
new_TestFixture(test_sixlowpan_sfr_rfrag_offset),
new_TestFixture(test_sixlowpan_sfr_ack_disp),
};
EMB_UNIT_TESTCALLER(sixlowpan_sfr_tests, NULL, NULL, fixtures);
return (Test *)&sixlowpan_sfr_tests;
}
void tests_sixlowpan_sfr(void)
{
TESTS_RUN(tests_sixlowpan_sfr_tests());
}
/** @} */

View File

@ -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.
*/
/**
* @addtogroup unittests
* @{
*
* @file
* @brief Unittests for the `sixlowpan_sfr` header
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef TESTS_SIXLOWPAN_SFR_H
#define TESTS_SIXLOWPAN_SFR_H
#include "embUnit.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief The entry point of this test suite.
*/
void tests_sixlowpan_sfr(void);
#ifdef __cplusplus
}
#endif
#endif /* TESTS_SIXLOWPAN_SFR_H */
/** @} */