1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/sys/shell/commands/sc_gnrc_6ctx.c
Martine Lenders c5fc7c44cd
shell: do not advertise reactively in 6ctx command
After thinking about it a bit, I decided to remove the reactive
advertisement of context information all together in the shell command.
RFC 6775 does not explicitly forbids, but it discourages multicast RAs,
which would be the alternative.
2017-11-17 16:32:14 +01:00

150 lines
4.1 KiB
C

/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* 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
*/
/* Required for strtok_r in string.h, when building with -std=c99 */
#define _DEFAULT_SOURCE 1
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "net/ipv6/addr.h"
#include "net/gnrc/sixlowpan/ctx.h"
#include "net/gnrc/sixlowpan/nd.h"
#include "timex.h"
#include "xtimer.h"
static xtimer_t del_timer[GNRC_SIXLOWPAN_CTX_SIZE];
void _del_cb(void *ptr)
{
gnrc_sixlowpan_ctx_t *ctx = ptr;
uint8_t cid = ctx->flags_id & GNRC_SIXLOWPAN_CTX_FLAGS_CID_MASK;
ctx->prefix_len = 0;
del_timer[cid].callback = NULL;
}
static void _usage(char *cmd_str)
{
printf("usage: %s [{add <0-15> <prefix>/<prefix_len> <ltime in min>|del <ctx>}]\n", cmd_str);
puts(" `del` will only invalidate the context for compression. It can be");
puts(" reassigned after 5 min.");
}
int _gnrc_6ctx_list(void)
{
puts("cid|prefix |C|ltime");
puts("-----------------------------------------------------------");
for (uint8_t i = 0; i < GNRC_SIXLOWPAN_CTX_SIZE; i++) {
gnrc_sixlowpan_ctx_t *ctx = gnrc_sixlowpan_ctx_lookup_id(i);
if (ctx != NULL) {
char addr_str[IPV6_ADDR_MAX_STR_LEN];
printf(" %2" PRIu8 "|%39s/%-3" PRIu8 "|%" PRIx8 "|%5" PRIu16 " min\n", i,
ipv6_addr_to_str(addr_str, &ctx->prefix, sizeof(addr_str)), ctx->prefix_len,
(uint8_t) ((ctx->flags_id & 0xf0) >> 4), ctx->ltime);
}
}
return 0;
}
int _gnrc_6ctx_add(char *cmd_str, char *ctx_str, char *prefix_str, char *ltime_str)
{
ipv6_addr_t prefix;
char *addr_str, *prefix_len_str, *save_ptr;
unsigned prefix_len;
unsigned ltime;
unsigned ctx = atoi(ctx_str);
if (ctx >= GNRC_SIXLOWPAN_CTX_SIZE) {
_usage(cmd_str);
return 1;
}
addr_str = strtok_r(prefix_str, "/", &save_ptr);
if (addr_str == NULL) {
_usage(cmd_str);
return 1;
}
prefix_len_str = strtok_r(NULL, "/", &save_ptr);
if (prefix_len_str == NULL) {
_usage(cmd_str);
return 1;
}
prefix_len = atoi(prefix_len_str);
if ((prefix_len - 1U) > 128U) {
puts("ERROR: prefix_len < 1 || prefix_len > 128");
return 1;
}
ipv6_addr_from_str(&prefix, addr_str);
if (ipv6_addr_is_unspecified(&prefix)) {
puts("ERROR: prefix may not be ::");
return 1;
}
ltime = atoi(ltime_str);
if (gnrc_sixlowpan_ctx_update((uint8_t)ctx, &prefix, (uint8_t)prefix_len, ltime,
true) == NULL) {
puts("ERROR: can not add context");
return 1;
}
return 0;
}
int _gnrc_6ctx_del(char *cmd_str, char *ctx_str)
{
gnrc_sixlowpan_ctx_t *ctx;
unsigned cid = atoi(ctx_str);
if (cid >= GNRC_SIXLOWPAN_CTX_SIZE) {
_usage(cmd_str);
return 1;
}
else if (del_timer[cid].callback == NULL) {
ctx = gnrc_sixlowpan_ctx_lookup_id(cid);
if (ctx != NULL) {
ctx->flags_id &= ~GNRC_SIXLOWPAN_CTX_FLAGS_COMP;
ctx->ltime = 0;
del_timer[cid].callback = _del_cb;
del_timer[cid].arg = ctx;
xtimer_set(&del_timer[cid], GNRC_SIXLOWPAN_ND_RTR_MIN_CTX_DELAY * US_PER_SEC);
}
}
else {
printf("Context %u already marked for removal\n", cid);
return 1;
}
/* advertise updated context */
_adv_ctx();
return 0;
}
int _gnrc_6ctx(int argc, char **argv)
{
if (argc < 2) {
_gnrc_6ctx_list();
}
else if (strcmp("add", argv[1]) == 0) {
if (argc < 5) {
_usage(argv[0]);
return 1;
}
return _gnrc_6ctx_add(argv[0], argv[2], argv[3], argv[4]);
}
else if (strcmp("del", argv[1]) == 0) {
return _gnrc_6ctx_del(argv[0], argv[2]);
}
else {
_usage(argv[0]);
return 1;
}
return 0;
}
/** @} */