Skip to content

Commit

Permalink
examples/gnrc_networking: provide bootstrapping for LoRaWAN/SCHC
Browse files Browse the repository at this point in the history
  • Loading branch information
miri64 committed Feb 22, 2023
1 parent c22d82c commit a7c9a18
Show file tree
Hide file tree
Showing 6 changed files with 297 additions and 0 deletions.
6 changes: 6 additions & 0 deletions examples/gnrc_networking/Makefile.board.dep
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
ifneq (,$(filter gnrc_lorawan,$(USEMODULE)))
KCONFIG_ADD_CONFIG += $(CURDIR)/lorawan.config
SHOULD_RUN_KCONFIG = 1
# include custom rules for SCHC over LoRaWAN
INCLUDES += -I$(CURDIR)/schc_lorawan/include
endif
4 changes: 4 additions & 0 deletions examples/gnrc_networking/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ you can of course write your own software, but you may have to bind the
socket to a specific interface (tap0 in this case). To do so, have a
look at [setting the `SO_BINDTODEVICE` option using `setsocketopt()`][sso].

## Using as an LPWAN/SCHC device

TODO

## Connecting two RIOT instances

When using native (i.e. when you're trying this on your Linux machine),
Expand Down
34 changes: 34 additions & 0 deletions examples/gnrc_networking/lorawan.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
CONFIG_KCONFIG_USEMODULE_GNRC_NETIF=y
CONFIG_KCONFIG_USEMODULE_LORAWAN=y

# Tell GNRC to encode LoRaWAN port in the GNRC netif header.
# This allows us to use `gnrc_txtsnd` to send data from the shell using the
# `txtsnd` command.
#
# Note: From Release 22.01 all GNRC LoRaWAN packets will include the netif
# header. Therefore this flag will be removed after that
CONFIG_GNRC_NETIF_LORAWAN_NETIF_HDR=y

# CONFIG_LORAMAC_APP_KEY_DEFAULT="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
# CONFIG_LORAMAC_NWK_KEY_DEFAULT="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
# CONFIG_LORAMAC_APP_EUI_DEFAULT="BBBBBBBBBBBBBBBB"
# CONFIG_LORAMAC_JOIN_EUI_DEFAULT="BBBBBBBBBBBBBBBB"
# CONFIG_LORAMAC_DEV_EUI_DEFAULT="CCCCCCCCCCCCCCCC"

# For TTN, It's necessary to set the RX2 DR to 3 in EU_868 region
# CONFIG_LORAMAC_DEFAULT_RX2_DR_3=y

# Comment/uncomment as necessary
CONFIG_LORAMAC_DEFAULT_JOIN_PROCEDURE_OTAA=y
# CONFIG_LORAMAC_DEFAULT_JOIN_PROCEDURE_ABP=y

# Uncomment and replace with proper keys for joining with ABP
# NOTE: This values will be overriten in case of OTAA.
# CONFIG_LORAMAC_DEV_ADDR_DEFAULT="00000000"
# CONFIG_LORAMAC_NWK_SKEY_DEFAULT="00000000000000000000000000000000"
# CONFIG_LORAMAC_APP_SKEY_DEFAULT="00000000000000000000000000000000"

## For FIT-IoT Lab usage. Use the highest DR since gateway is nearby.
# If uncommented, the default value (DR0) is used.
# Note this value is also used for the OTAA.
# CONFIG_LORAMAC_DEFAULT_DR_5=y
6 changes: 6 additions & 0 deletions examples/gnrc_networking/schc_lorawan/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SCHC rule configuration for LoRaWAN nodes
=========================================

This contains the SCHC rule configuration for LoRaWAN nodes. See [libSCHC] for more information.

[libSCHC]: https://github.com/imec-idlab/libschc
37 changes: 37 additions & 0 deletions examples/gnrc_networking/schc_lorawan/include/rules/rule_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2018 imec IDLab
* Copyright (C) 2022 Freie Universität Berlin
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* @internal
* @author boortmans <bart.moons@gmail.com>
* @author Martine S. Lenders <m.lenders@fu-berlin.de>
*/
#ifndef RULES_RULE_CONFIG_H
#define RULES_RULE_CONFIG_H

#include "rules.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#endif /* RULES_RULE_CONFIG_H */
210 changes: 210 additions & 0 deletions examples/gnrc_networking/schc_lorawan/include/rules/rules.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/*
* Copyright (C) 2018 imec IDLab
* Copyright (C) 2022 Freie Universität Berlin
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* @internal
* @author boortmans <bart.moons@gmail.com>
* @author Martine S. Lenders <m.lenders@fu-berlin.de>
*/
#ifndef RULES_RULES_H
#define RULES_RULES_H

#include "kernel_defines.h"

#include "schc.h"
#ifdef USE_COAP
#include "net/coap.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if USE_IP6
/* ICMPv6 headers */
static const struct schc_ipv6_rule_t ipv6_rule1 = {
.up = 10, .down = 10, .length = 12,
{
/* field, ML, len, pos, dir, val, MO, CDA */
{ IP6_V, 0, 4, 1, BI, {6}, &mo_equal, NOTSENT },
{ IP6_TC, 0, 8, 1, BI, {0}, &mo_ignore, NOTSENT },
{ IP6_FL, 0, 20, 1, BI, {0, 0, 0}, &mo_ignore, NOTSENT },
{ IP6_LEN, 0, 16, 1, BI, {0, 0}, &mo_ignore, COMPLENGTH },
{ IP6_NH, 0, 8, 1, BI, {58}, &mo_equal, NOTSENT },
{ IP6_HL, 2, 8, 1, BI, {64, 255}, &mo_matchmap, MAPPINGSENT },
{ IP6_DEVPRE, 2, 64, 1, DOWN, {
0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}, &mo_matchmap, MAPPINGSENT },
{ IP6_DEVPRE, 0, 64, 1, UP, {
0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}, &mo_equal, NOTSENT },
/* TODO use DEVIID once it is implemented in libSCHC */
{ IP6_DEVIID, 0, 64, 1, BI, {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}, &mo_ignore, VALUESENT },
{ IP6_APPPRE, 2, 64, 1, UP, {
0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}, &mo_matchmap, MAPPINGSENT },
{ IP6_APPPRE, 0, 64, 1, DOWN, {
0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}, &mo_equal, NOTSENT },
{ IP6_APPIID, 0, 64, 1, BI, {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}, &mo_ignore, VALUESENT },
}
};

/* UDP link-local headers */
static const struct schc_ipv6_rule_t ipv6_rule2 = {
.up = 10, .down = 10, .length = 11,
{
/* field, ML, len, pos, dir, val, MO, CDA */
{ IP6_V, 0, 4, 1, BI, {6}, &mo_equal, NOTSENT },
{ IP6_TC, 0, 8, 1, BI, {0}, &mo_ignore, NOTSENT },
{ IP6_FL, 0, 20, 1, BI, {0, 0, 0}, &mo_ignore, NOTSENT },
{ IP6_LEN, 0, 16, 1, BI, {0, 0}, &mo_ignore, COMPLENGTH },
{ IP6_NH, 0, 8, 1, BI, {17}, &mo_equal, NOTSENT },
{ IP6_HL, 2, 8, 1, UP, {64}, &mo_equal, NOTSENT },
{ IP6_HL, 2, 8, 1, DOWN, {0}, &mo_ignore, VALUESENT },
{ IP6_DEVPRE, 0, 64, 1, BI, {
0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}, &mo_equal, NOTSENT },
/* TODO use DEVIID once it is implemented in libSCHC */
{ IP6_DEVIID, 0, 64, 1, BI, {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}, &mo_ignore, VALUESENT },
{ IP6_APPPRE, 0, 64, 1, BI, {
0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}, &mo_equal, NOTSENT },
{ IP6_APPIID, 0, 64, 1, BI, {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}, &mo_ignore, VALUESENT },
}
};
#endif

#if USE_UDP
/* TODO fit for udp command */
static const struct schc_udp_rule_t udp_rule1 = {
.up = 4, .down = 4, .length = 4,
{
/* field, ML, len, pos, dir, val, MO, CDA */
/* set field length to 16 to indicate 16 bit values
* MO param length to 2 to indicate 2 indices */
{ UDP_DEV, 2, 16, 1, BI, {0, 0}, &mo_ignore, VALUESENT},
{ UDP_APP, 2, 16, 1, BI, {0, 0}, &mo_ignore, VALUESENT},
{ UDP_LEN, 0, 16, 1, BI, {0, 0}, &mo_ignore, COMPLENGTH },
{ UDP_CHK, 0, 16, 1, BI, {0, 0}, &mo_ignore, COMPCHK },
}
};
#endif

static const struct schc_compression_rule_t comp_rule_1 = {
.rule_id = 0x01,
.rule_id_size_bits = 8,
#if USE_IP6
&ipv6_rule1,
#endif
#if USE_UDP
NULL,
#endif
#if USE_COAP
NULL,
#endif
};

static const struct schc_compression_rule_t comp_rule_2 = {
.rule_id = 0x02,
.rule_id_size_bits = 8,
#if USE_IP6
&ipv6_rule2,
#endif
#if USE_UDP
&udp_rule1,
#endif
#if USE_COAP
NULL,
#endif
};

static const struct schc_fragmentation_rule_t frag_rule_20 = {
.rule_id = 20,
.rule_id_size_bits = 8,
.mode = ACK_ON_ERROR,
.dir = UP,
.FCN_SIZE = 6, /* FCN size */
.MAX_WND_FCN = 62, /* Maximum fragments per window */
.WINDOW_SIZE = 2, /* Window size */
.DTAG_SIZE = 0, /* DTAG size */
};

static const struct schc_fragmentation_rule_t frag_rule_21 = {
.rule_id = 21,
.rule_id_size_bits = 8,
.mode = ACK_ALWAYS,
.dir = DOWN,
.FCN_SIZE = 1, /* FCN size */
.MAX_WND_FCN = 1, /* Maximum fragments per window */
.WINDOW_SIZE = 1, /* Window size */
.DTAG_SIZE = 0, /* DTAG size */
};

static const struct schc_fragmentation_rule_t frag_rule_23 = {
.rule_id = 23,
.rule_id_size_bits = 8,
.mode = NO_ACK,
.dir = DOWN,
.FCN_SIZE = 1, /* FCN size */
.MAX_WND_FCN = 1, /* Maximum fragments per window */
.WINDOW_SIZE = 1, /* Window size */
.DTAG_SIZE = 0, /* DTAG size */
};

/* save compression rules in flash */
static const struct schc_compression_rule_t* node1_compression_rules[] = {
&comp_rule_1, &comp_rule_2,
};

/* save fragmentation rules in flash */
static const struct schc_fragmentation_rule_t* node1_fragmentation_rules[] = {
&frag_rule_20, &frag_rule_21,
};

/* rules for a particular device */
static const struct schc_device node1 = {
.device_id = 1,
.uncomp_rule_id = 22, /* see https://datatracker.ietf.org/doc/html/rfc9011#section-5.2 */
.uncomp_rule_id_size_bits = 8,
.compression_rule_count = ARRAY_SIZE(node1_compression_rules),
.compression_context = &node1_compression_rules,
.fragmentation_rule_count = ARRAY_SIZE(node1_fragmentation_rules),
.fragmentation_context = &node1_fragmentation_rules
};

/* server keeps track of multiple devices: add devices to device list */
static const struct schc_device* devices[] = { &node1 };

#define DEVICE_COUNT ((int)ARRAY_SIZE(devices))

#ifdef __cplusplus
}
#endif

#endif /* RULES_RULES_H */

0 comments on commit a7c9a18

Please # to comment.