diff --git a/sys/include/net/ng_sixlowpan/ctx.h b/sys/include/net/ng_sixlowpan/ctx.h index dddfaa11e6..6d5b7a1483 100644 --- a/sys/include/net/ng_sixlowpan/ctx.h +++ b/sys/include/net/ng_sixlowpan/ctx.h @@ -30,6 +30,7 @@ #define NG_SIXLOWPAN_CTX_H_ #include +#include #include "net/ng_ipv6/addr.h" @@ -40,6 +41,17 @@ extern "C" { #define NG_SIXLOWPAN_CTX_SIZE (16) /**< maximum number of entries in * context buffer */ +/** + * @{ + * @name Context flags. + * @brief Flags to set in ng_sixlowpan_ctx_t::flags_id. + */ +#define NG_SIXLOWPAN_CTX_FLAGS_CID_MASK (0x0f) /**< mask for the Context ID. */ +#define NG_SIXLOWPAN_CTX_FLAGS_COMP (0x10) /**< Use context for compression */ +/** + * @} + */ + /** * @brief Entry in the 6LoWPAN context buffer. */ @@ -47,12 +59,14 @@ typedef struct { ng_ipv6_addr_t prefix; /**< The prefix associated to this context. */ uint8_t prefix_len; /**< Length of ng_sixlowpan_ctx_t::prefix in bit. */ /** - * @brief 4-bit Context ID. + * @brief 4-bit flags, 4-bit Context ID. * * @note This needs to be here to easily translate prefixes to * ID. + * + * @details The flags are defined as above. */ - uint8_t id; + uint8_t flags_id; /** * @brief Lifetime in minutes this context is valid. * @@ -89,17 +103,28 @@ ng_sixlowpan_ctx_t *ng_sixlowpan_ctx_lookup_id(uint8_t id); * @param[in] id The ID for the context. * Must be < @ref NG_SIXLOWPAN_CTX_SIZE. * @param[in] prefix The prefix for the context. - * @param[in] prefix_len Length of @p prefix in bits. Must be > 0, when - * @p ltime > 0. - * @param[in] ltime New lifetime of the context. The context will - * be removed if 0. + * @param[in] prefix_len Length of @p prefix in bits. Must be > 0. + * @param[in] ltime New lifetime of the context. @p comp will be + * implicitly set to `false` if @p ltime == 0. + * @param[in] comp Use for compression if true, do not use for + * compression, but still for decompression if false. * * @return The new context on success. * @return NULL, on error or on removal. */ ng_sixlowpan_ctx_t *ng_sixlowpan_ctx_update(uint8_t id, const ng_ipv6_addr_t *prefix, - uint8_t prefix_len, uint16_t ltime); + uint8_t prefix_len, uint16_t ltime, + bool comp); +/** + * @brief Removes context. + * + * @param[in] id A context ID. + */ +static inline void ng_sixlowpan_ctx_remove(uint8_t id) +{ + ng_sixlowpan_ctx_lookup_id(id)->prefix_len = 0; +} #ifdef TEST_SUITES /** diff --git a/sys/net/network_layer/ng_sixlowpan/ctx/ng_sixlowpan_ctx.c b/sys/net/network_layer/ng_sixlowpan/ctx/ng_sixlowpan_ctx.c index 7d4752c41a..3c24823e0f 100644 --- a/sys/net/network_layer/ng_sixlowpan/ctx/ng_sixlowpan_ctx.c +++ b/sys/net/network_layer/ng_sixlowpan/ctx/ng_sixlowpan_ctx.c @@ -27,16 +27,16 @@ static uint32_t _ctx_inval_times[NG_SIXLOWPAN_CTX_SIZE]; static mutex_t _ctx_mutex = MUTEX_INIT; static uint32_t _current_minute(void); -static void _update_lifetime(unsigned int id); +static void _update_lifetime(uint8_t id); #if ENABLE_DEBUG static char ipv6str[NG_IPV6_ADDR_MAX_STR_LEN]; #endif -static inline bool _still_valid(unsigned int id) +static inline bool _valid(uint8_t id) { _update_lifetime(id); - return (_ctxs[id].ltime > 0); + return (_ctxs[id].prefix_len > 0); } ng_sixlowpan_ctx_t *ng_sixlowpan_ctx_lookup_addr(const ng_ipv6_addr_t *addr) @@ -47,7 +47,7 @@ ng_sixlowpan_ctx_t *ng_sixlowpan_ctx_lookup_addr(const ng_ipv6_addr_t *addr) mutex_lock(&_ctx_mutex); for (unsigned int id = 0; id < NG_SIXLOWPAN_CTX_SIZE; id++) { - if (_still_valid(id)) { + if (_valid(id)) { uint8_t match = ng_ipv6_addr_match_prefix(&_ctxs[id].prefix, addr); if ((_ctxs[id].prefix_len <= match) && (match > best)) { @@ -79,7 +79,7 @@ ng_sixlowpan_ctx_t *ng_sixlowpan_ctx_lookup_id(uint8_t id) mutex_lock(&_ctx_mutex); - if (_still_valid((unsigned int)id)) { + if (_valid(id)) { DEBUG("6lo ctx: found context (%u, %s/%" PRIu8 ")\n", id, ng_ipv6_addr_to_str(ipv6str, &_ctxs[id].prefix, sizeof(ipv6str)), _ctxs[id].prefix_len); @@ -93,9 +93,10 @@ ng_sixlowpan_ctx_t *ng_sixlowpan_ctx_lookup_id(uint8_t id) } ng_sixlowpan_ctx_t *ng_sixlowpan_ctx_update(uint8_t id, const ng_ipv6_addr_t *prefix, - uint8_t prefix_len, uint16_t ltime) + uint8_t prefix_len, uint16_t ltime, + bool comp) { - if ((id >= NG_SIXLOWPAN_CTX_SIZE)) { + if ((id >= NG_SIXLOWPAN_CTX_SIZE) || (prefix_len == 0)) { return NULL; } @@ -104,19 +105,7 @@ ng_sixlowpan_ctx_t *ng_sixlowpan_ctx_update(uint8_t id, const ng_ipv6_addr_t *pr _ctxs[id].ltime = ltime; if (ltime == 0) { - mutex_unlock(&_ctx_mutex); - DEBUG("6lo ctx: remove context (%u, %s/%" PRIu8 ")\n", id, - ng_ipv6_addr_to_str(ipv6str, &_ctxs[id].prefix, sizeof(ipv6str)), - _ctxs[id].prefix_len); - return NULL; - } - - /* test prefix_len now so that invalidation is possible regardless of the - * value. */ - if (prefix_len == 0) { - mutex_unlock(&_ctx_mutex); - _ctxs[id].ltime = 0; - return NULL; + comp = false; } if (prefix_len > NG_IPV6_ADDR_BIT_LEN) { @@ -126,7 +115,7 @@ ng_sixlowpan_ctx_t *ng_sixlowpan_ctx_update(uint8_t id, const ng_ipv6_addr_t *pr _ctxs[id].prefix_len = prefix_len; } - _ctxs[id].id = id; + _ctxs[id].flags_id = (comp) ? (NG_SIXLOWPAN_CTX_FLAGS_COMP | id) : id; if (!ng_ipv6_addr_equal(&(_ctxs[id].prefix), prefix)) { ng_ipv6_addr_set_unspecified(&(_ctxs[id].prefix)); @@ -150,19 +139,21 @@ static uint32_t _current_minute(void) return now.seconds / 60; } -static void _update_lifetime(unsigned int id) +static void _update_lifetime(uint8_t id) { uint32_t now; if (_ctxs[id].ltime == 0) { + _ctxs[id].flags_id &= ~NG_SIXLOWPAN_CTX_FLAGS_COMP; return; } now = _current_minute(); if (now >= _ctx_inval_times[id]) { - DEBUG("6lo ctx: context %u was invalidated\n", id); + DEBUG("6lo ctx: context %u was invalidated for compression\n", id); _ctxs[id].ltime = 0; + _ctxs[id].flags_id &= ~NG_SIXLOWPAN_CTX_FLAGS_COMP; } else { _ctxs[id].ltime = (uint16_t)(_ctx_inval_times[id] - now);