Skip to content

Commit

Permalink
Merge pull request #17884 from Ollrogge/gnrc_lorawan1.1
Browse files Browse the repository at this point in the history
gnrc/lorawan: add basic LoRaWAN 1.1 features
  • Loading branch information
jia200x authored Sep 30, 2022
2 parents 3ee3d1b + 32cef70 commit f022ac3
Show file tree
Hide file tree
Showing 24 changed files with 2,068 additions and 633 deletions.
4 changes: 4 additions & 0 deletions examples/gnrc_lorawan/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ USEMODULE += auto_init_gnrc_netif

# Add support for GNRC LoRaWAN
USEMODULE += gnrc_lorawan
# Add support for GNRC LoRaWAN 1.1
# USEMODULE += gnrc_lorawan_1_1

# Use GNRC pktdump to print downlink messages
USEMODULE += gnrc_pktdump
Expand Down Expand Up @@ -55,7 +57,9 @@ ifndef CONFIG_KCONFIG_USEMODULE_LORAWAN
CFLAGS += -DCONFIG_GNRC_NETIF_LORAWAN_NETIF_HDR

CFLAGS += -DCONFIG_LORAMAC_APP_KEY_DEFAULT=\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"
CFLAGS += -DCONFIG_LORAMAC_NWK_KEY_DEFAULT=\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"
CFLAGS += -DCONFIG_LORAMAC_APP_EUI_DEFAULT=\"BBBBBBBBBBBBBBBB\"
CFLAGS += -DCONFIG_LORAMAC_JOIN_EUI_DEFAULT=\"BBBBBBBBBBBBBBBB\"
CFLAGS += -DCONFIG_LORAMAC_DEV_EUI_DEFAULT=\"CCCCCCCCCCCCCCCC\"

# For TTN, It's necessary to set the RX2 DR to 3 in EU_868 region
Expand Down
4 changes: 2 additions & 2 deletions examples/lorawan/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ static uint8_t appskey[LORAMAC_APPSKEY_LEN];

static void _alarm_cb(void *arg)
{
(void) arg;
(void)arg;
msg_t msg;
msg_send(&msg, sender_pid);
}
Expand All @@ -98,7 +98,7 @@ static void _send_message(void)
/* Try to send the message */
uint8_t ret = semtech_loramac_send(&loramac,
(uint8_t *)message, strlen(message));
if (ret != SEMTECH_LORAMAC_TX_DONE) {
if (ret != SEMTECH_LORAMAC_TX_DONE) {
printf("Cannot send message '%s', ret code: %d\n", message, ret);
return;
}
Expand Down
1 change: 1 addition & 0 deletions makefiles/pseudomodules.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ PSEUDOMODULES += gnrc_ipv6_nib_dns
PSEUDOMODULES += gnrc_ipv6_nib_rio
PSEUDOMODULES += gnrc_ipv6_nib_router
PSEUDOMODULES += gnrc_ipv6_nib_rtr_adv_pio_cb
PSEUDOMODULES += gnrc_lorawan_1_1
PSEUDOMODULES += gnrc_netdev_default
PSEUDOMODULES += gnrc_neterr
PSEUDOMODULES += gnrc_netapi_callbacks
Expand Down
6 changes: 3 additions & 3 deletions sys/include/net/gnrc/lorawan.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,10 @@ void gnrc_lorawan_timeout_cb(gnrc_lorawan_t *mac);
* @brief Init GNRC LoRaWAN
*
* @param[in] mac pointer to the MAC descriptor
* @param[in] nwkskey buffer to store the NwkSKey. Should be at least 16 bytes long
* @param[in] appskey buffer to store the AppsKey. Should be at least 16 bytes long
* @param[in] joineui pointer to Join EUI
* @param[in] ctx pointer to LoRaWAN context
*/
void gnrc_lorawan_init(gnrc_lorawan_t *mac, uint8_t *nwkskey, uint8_t *appskey);
void gnrc_lorawan_init(gnrc_lorawan_t *mac, uint8_t *joineui, const gnrc_lorawan_key_ctx_t *ctx);

/**
* @brief Perform a MLME request
Expand Down
140 changes: 125 additions & 15 deletions sys/include/net/gnrc/netif/lorawan.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,133 @@ extern "C" {
* @brief GNRC LoRaWAN interface descriptor
*/
typedef struct {
uint8_t nwkskey[LORAMAC_NWKSKEY_LEN]; /**< network SKey buffer */
uint8_t appskey[LORAMAC_APPSKEY_LEN]; /**< App SKey buffer */
uint8_t appkey[LORAMAC_APPKEY_LEN]; /**< App Key buffer */
uint8_t deveui[LORAMAC_DEVEUI_LEN]; /**< Device EUI buffer */
uint8_t appeui[LORAMAC_APPEUI_LEN]; /**< App EUI buffer */
gnrc_lorawan_t mac; /**< gnrc lorawan mac descriptor */
ztimer_t timer; /**< General purpose timer */
ztimer_t backoff_timer; /**< Backoff timer */
uint8_t flags; /**< flags for the LoRaWAN interface */
uint8_t demod_margin; /**< value of last demodulation margin */
uint8_t num_gateways; /**< number of gateways of last link check */
uint8_t datarate; /**< LoRaWAN datarate for the next transmission */
uint8_t port; /**< LoRaWAN port for the next transmission */
uint8_t ack_req; /**< Request ACK in the next transmission */
uint8_t otaa; /**< whether the next transmission is OTAA or not */
uint8_t appskey[LORAMAC_APPSKEY_LEN]; /**< App SKey buffer */
uint8_t fnwksintkey[LORAMAC_FNWKSINTKEY_LEN]; /**< Forwarding Network session integrity key buffer */
uint8_t nwkkey[LORAMAC_NWKKEY_LEN]; /**< Network key buffer. Mapped to AppKey if LoRaWAN 1.0x */
#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
uint8_t appkey[LORAMAC_APPKEY_LEN]; /**< App Key buffer. The AppKey used in LoRaWAN 1.0x has been mapped to the nwkkey in LoRaWAN 1.1x */
uint8_t snwksintkey[LORAMAC_SNWKSINTKEY_LEN]; /**< Serving Network session integrity key buffer */
uint8_t nwksenckey[LORAMAC_NWKSENCKEY_LEN]; /**< Network session encryption key buffer */
uint8_t jsintkey[LORAMAC_JSINTKEY_LEN]; /**< Join session integrity key buffer */
uint8_t jsenckey[LORAMAC_JSENCKEY_LEN]; /**< Join session encryption key buffer */
#endif
uint8_t deveui[LORAMAC_DEVEUI_LEN]; /**< Device EUI buffer */
uint8_t joineui[LORAMAC_JOINEUI_LEN]; /**< Join EUI buffer */
gnrc_lorawan_t mac; /**< gnrc lorawan mac descriptor */
ztimer_t timer; /**< General purpose timer */
ztimer_t backoff_timer; /**< Backoff timer */
uint8_t flags; /**< flags for the LoRaWAN interface */
uint8_t demod_margin; /**< value of last demodulation margin */
uint8_t num_gateways; /**< number of gateways of last link check */
uint8_t datarate; /**< LoRaWAN datarate for the next transmission */
uint8_t port; /**< LoRaWAN port for the next transmission */
uint8_t ack_req; /**< Request ACK in the next transmission */
uint8_t otaa; /**< whether the next transmission is OTAA or not */
} gnrc_netif_lorawan_t;

/**
* @brief Set the app key in the interface descriptor
*
* This getter function exists to allow if (IS_USED(...)) constructs in the
* LoRaWAN code in order to increase code coverage.
*
* @param[in] lw_netif pointer to the interface descriptor
* @param[in] key pointer to the app key
* @param[in] len length of the app key
* @return 0 on success
* @return <0 on failure
*/
static inline int gnrc_netif_lorawan_set_appkey(gnrc_netif_lorawan_t *lw_netif, const uint8_t *key,
size_t len)
{
(void)lw_netif;
(void)key;
(void)len;

#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
if (sizeof(lw_netif->appkey) < len) {
return -1;
}
memcpy(lw_netif->appkey, key, len);
#endif
return 0;
}

/**
* @brief Get the app key from the interface descriptor
*
* This getter function exists to allow if (IS_USED(...)) constructs in the
* LoRaWAN code in order to increase code coverage.
*
* @param[in] lw_netif pointer to the interface descriptor
* @return pointer to the app key
*/
static inline uint8_t * gnrc_netif_lorawan_get_appkey(gnrc_netif_lorawan_t *lw_netif)
{
(void)lw_netif;

#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
return lw_netif->appkey;
#endif
return NULL; /* NO-OP */
}

/**
* @brief Set the serving network session integrity key in the interface descriptor
*
* This getter function exists to allow if (IS_USED(...)) constructs in the
* LoRaWAN code in order to increase code coverage.
*
* @param[in] lw_netif pointer to the interface descriptor
* @param[in] key pointer to the serving network session integrity key
* @param[in] len length of serving network session integrity key
* @return 0 on success
* @return <0 on failure
*/
static inline int gnrc_netif_lorawan_set_snwksintkey(gnrc_netif_lorawan_t *lw_netif,
const uint8_t *key, size_t len)
{
(void)lw_netif;
(void)key;
(void)len;

#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
if (sizeof(lw_netif->snwksintkey) < len) {
return -1;
}
memcpy(lw_netif->snwksintkey, key, len);
#endif
return 0;
}

/**
* @brief Set the network session encryption key in the interface descriptor
*
* This getter function exists to allow if (IS_USED(...)) constructs in the
* LoRaWAN code in order to increase code coverage.
*
* @param[in] lw_netif pointer to the interface descriptor
* @param[in] key pointer to the network session encryption key
* @param[in] len length of network session encryption key
* @return 0 on success
* @return <0 on failure
*/
static inline int gnrc_netif_lorawan_set_nwksenckey(gnrc_netif_lorawan_t *lw_netif,
const uint8_t *key, size_t len)
{
(void)lw_netif;
(void)key;
(void)len;

#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
if (sizeof(lw_netif->nwksenckey) < len) {
return -1;
}
memcpy(lw_netif->nwksenckey, key, len);
#endif
return 0;
}

#ifdef __cplusplus
}
#endif
Expand Down
90 changes: 90 additions & 0 deletions sys/include/net/loramac.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ extern "C" {
#define CONFIG_LORAMAC_DEV_EUI_DEFAULT "0000000000000000"
#endif

/**
* @brief Default join EUI
*
* 8 bytes key, required for join procedure
*/
#ifndef CONFIG_LORAMAC_JOIN_EUI_DEFAULT
#define CONFIG_LORAMAC_JOIN_EUI_DEFAULT "0000000000000000"
#endif

/**
* @brief Default application EUI
*
Expand All @@ -64,6 +73,15 @@ extern "C" {
#define CONFIG_LORAMAC_APP_KEY_DEFAULT "00000000000000000000000000000000"
#endif

/**
* @brief Default network key
*
* 16 bytes key, required for join procedure
*/
#ifndef CONFIG_LORAMAC_NWK_KEY_DEFAULT
#define CONFIG_LORAMAC_NWK_KEY_DEFAULT "00000000000000000000000000000000"
#endif

/**
* @brief Default application session key
*
Expand All @@ -82,6 +100,33 @@ extern "C" {
#define CONFIG_LORAMAC_NWK_SKEY_DEFAULT "00000000000000000000000000000000"
#endif

/**
* @brief Default network session integrity key
*
* 16 bytes key, required for join procedure
*/
#ifndef CONFIG_LORAMAC_FNWKSINT_KEY_DEFAULT
#define CONFIG_LORAMAC_FNWKSINT_KEY_DEFAULT "00000000000000000000000000000000"
#endif

/**
* @brief Default serving network session integrity key
*
* 16 bytes key, required for join procedure
*/
#ifndef CONFIG_LORAMAC_SNWKSINT_KEY_DEFAULT
#define CONFIG_LORAMAC_SNWKSINT_KEY_DEFAULT "00000000000000000000000000000000"
#endif

/**
* @brief Default network session encryption key
*
* 16 bytes key, required for join procedure
*/
#ifndef CONFIG_LORAMAC_NWKSENC_KEY_DEFAULT
#define CONFIG_LORAMAC_NWKSENC_KEY_DEFAULT "00000000000000000000000000000000"
#endif

/**
* @brief Default device address
*/
Expand Down Expand Up @@ -514,11 +559,21 @@ extern "C" {
*/
#define LORAMAC_APPEUI_LEN (8U)

/**
* @brief Join EUI length in bytes
*/
#define LORAMAC_JOINEUI_LEN (8U)

/**
* @brief Application key length in bytes
*/
#define LORAMAC_APPKEY_LEN (16U)

/**
* @brief Network key length in bytes
*/
#define LORAMAC_NWKKEY_LEN (16U)

/**
* @brief Application session key length in bytes
*/
Expand All @@ -529,6 +584,36 @@ extern "C" {
*/
#define LORAMAC_NWKSKEY_LEN (16U)

/**
* @brief Forwarding Network session integrity key length in bytes
*/
#define LORAMAC_FNWKSINTKEY_LEN (16U)

/**
* @brief Serving Network session integrity key length in bytes
*/
#define LORAMAC_SNWKSINTKEY_LEN (16U)

/**
* @brief Network session encryption key length in bytes
*/
#define LORAMAC_NWKSENCKEY_LEN (16U)

/**
* @brief Join session integrity key length in bytes
*/
#define LORAMAC_JSINTKEY_LEN (16U)

/**
* @brief Join session encryption key length in bytes
*/
#define LORAMAC_JSENCKEY_LEN (16U)

/**
* @brief Network session encryption key length in bytes
*/
#define LORAMAC_JSINTKEY_LEN (16U)

/**
* @brief Minimum port value
*/
Expand All @@ -544,6 +629,11 @@ extern "C" {
*/
#define LORAMAC_APP_NONCE_LEN (3U)

/**
* @brief Join nonce length in bytes
*/
#define LORAMAC_JOIN_NONCE_LEN (3U)

/**
* @brief Network ID length in bytes
*/
Expand Down
19 changes: 17 additions & 2 deletions sys/include/net/lorawan/hdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
#define LORAWAN_HDR_FOPTS_LEN_MASK (0x0F) /**< Frame options mask */
#define LORAWAN_HDR_FOPTS_LEN_POS (0U) /**< Frame options position */

#define LORAWAN_JA_HDR_OPTNEG_MASK (0x80) /**< OptNeg bit mask */
#define LORAWAN_JA_HDR_OPTNEG_POS (7U) /**< OptNeg bit position */

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -92,7 +95,7 @@ typedef struct __attribute__((packed)) {
*/
typedef struct __attribute__((packed)) {
uint8_t mt_maj; /**< mtype and major version holder */
le_uint64_t app_eui; /**< application EUI */
le_uint64_t join_eui; /**< join EUI. Mapped to app EUI if LoRaWAN 1.0x */
le_uint64_t dev_eui; /**< device EUI */
le_uint16_t dev_nonce; /**< device nonce */
le_uint32_t mic; /**< message integrity code */
Expand All @@ -103,7 +106,7 @@ typedef struct __attribute__((packed)) {
*/
typedef struct __attribute__((packed)) {
uint8_t mt_maj; /**< mtype and major version holder */
uint8_t app_nonce[LORAMAC_APP_NONCE_LEN]; /**< application nonce */
uint8_t join_nonce[LORAMAC_JOIN_NONCE_LEN]; /**< join nonce. Mapped to application nonce if LoRaWAN 1.0x */
uint8_t net_id[LORAMAC_NETWORK_ID_LEN]; /**< network id */
uint8_t dev_addr[LORAMAC_DEVADDR_LEN]; /**< device address */
uint8_t dl_settings; /**< downlink settings */
Expand Down Expand Up @@ -278,6 +281,18 @@ static inline uint8_t lorawan_hdr_get_frame_opts_len(lorawan_hdr_t *hdr)
return (hdr->fctrl & LORAWAN_HDR_FOPTS_LEN_MASK) >> LORAWAN_HDR_FOPTS_LEN_POS;
}

/**
* @brief Get LoRaWAN join accept message OptNeg bit
*
* @param[in] ja_hdr Join accept message header
*
* @return value of the OptNeg bit
*/
static inline bool lorawan_ja_hdr_get_optneg(lorawan_join_accept_t *ja_hdr)
{
return (ja_hdr->dl_settings & LORAWAN_JA_HDR_OPTNEG_MASK) >> LORAWAN_JA_HDR_OPTNEG_POS;
}

#ifdef __cplusplus
}
#endif
Expand Down
Loading

0 comments on commit f022ac3

Please sign in to comment.