Loading...
Searching...
No Matches
gnrc_lorawan_internal.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2019 HAW Hamburg
3 * SPDX-License-Identifier: LGPL-2.1-only
4 */
5
6#pragma once
7
17
18#include <stdio.h>
19#include <string.h>
20#include "iolist.h"
21#include "net/lora.h"
22#include "net/lorawan/hdr.h"
23#include "net/gnrc/pktbuf.h"
24#include "net/netdev.h"
25#include "net/loramac.h"
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#define MSG_TYPE_TIMEOUT (0x3457)
32
33#define MTYPE_MASK 0xE0
34#define MTYPE_JOIN_REQUEST 0x0
35#define MTYPE_JOIN_ACCEPT 0x1
36#define MTYPE_UNCNF_UPLINK 0x2
37#define MTYPE_UNCNF_DOWNLINK 0x3
38#define MTYPE_CNF_UPLINK 0x4
39#define MTYPE_CNF_DOWNLINK 0x5
40#define MTYPE_REJOIN_REQ 0x6
41#define MTYPE_PROPIETARY 0x7
42
43#define MAJOR_MASK 0x3
44#define MAJOR_LRWAN_R1 0x0
45
46#define MINOR_LRWAN 0x1
47
48#define JOIN_REQUEST_SIZE (23U)
49#define MIC_SIZE (4U)
50#define CFLIST_SIZE (16U)
51
52#define GNRC_LORAWAN_MAX_CHANNELS (16U)
53
54#define LORAWAN_STATE_IDLE (0)
55#define LORAWAN_STATE_RX_1 (1)
56#define LORAWAN_STATE_RX_2 (2)
57#define LORAWAN_STATE_TX (3)
58#define LORAWAN_STATE_JOIN (4)
59
60#define GNRC_LORAWAN_DIR_UPLINK (0U)
61#define GNRC_LORAWAN_DIR_DOWNLINK (1U)
62
63#define GNRC_LORAWAN_BACKOFF_WINDOW_TICK (3600000000LL)
64
65#define GNRC_LORAWAN_BACKOFF_BUDGET_1 (36000000LL)
66#define GNRC_LORAWAN_BACKOFF_BUDGET_2 (36000000LL)
67#define GNRC_LORAWAN_BACKOFF_BUDGET_3 (8700000LL)
68
69#define GNRC_LORAWAN_MLME_OPTS_LINK_CHECK_REQ (1 << 0)
70#define GNRC_LORAWAN_MLME_OPTS_REKEY_IND_REQ (1 << 1)
71
72#define GNRC_LORAWAN_CID_SIZE (1U)
73#define GNRC_LORAWAN_CID_LINK_CHECK_ANS (0x02)
74
75#define GNCR_LORAWAN_REKEY_IND_SIZE (1U)
76#define GNCR_LORAWAN_CID_REKEY_CONF (0x0B)
77
78#define GNRC_LORAWAN_FOPT_LINK_CHECK_ANS_SIZE (3U)
79#define GNRC_LORAWAN_FOPT_REKEY_CONF_SIZE (2U)
80
81#define GNRC_LORAWAN_JOIN_DELAY_U32_MASK (0x1FFFFF)
82
83#define GNRC_LORAWAN_MAX_PAYLOAD_1 (59U)
84#define GNRC_LORAWAN_MAX_PAYLOAD_2 (123U)
85#define GNRC_LORAWAN_MAX_PAYLOAD_3 (250U)
86
87#define GNRC_LORAWAN_CFLIST_ENTRY_SIZE (3U)
88#define GNRC_LORAWAN_JOIN_ACCEPT_MAX_SIZE (33U)
89
90#define GNRC_LORAWAN_BACKOFF_STATE_1 (0U)
91#define GNRC_LORAWAN_BACKOFF_STATE_2 (1U)
92#define GNRC_LORAWAN_BACKOFF_STATE_3 (2U)
93
94#define GNRC_LORAWAN_BACKOFF_TIME_1 (1U)
95#define GNRC_LORAWAN_BACKOFF_TIME_2 (10U)
96#define GNRC_LORAWAN_BACKOFF_TIME_3 (24U)
97
98#define GNRC_LORAWAN_APP_NONCE_SIZE (3U)
99#define GNRC_LORAWAN_JOIN_NONCE_SIZE (3U)
100#define GNRC_LORAWAN_NET_ID_SIZE (3U)
101#define GNRC_LORAWAN_DEV_NONCE_SIZE (2U)
102
103#define GNRC_LORAWAN_FOPTS_MAX_SIZE (15U)
104#define GNRC_LORAWAN_FPORT_SIZE (1U)
105
106#if defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) || \
107 defined(CPU_FAM_STM32F7)
108#define GNRC_LORAWAN_STATE_FLASHPAGE_NUM (0x7)
109#else
110#define GNRC_LORAWAN_STATE_FLASHPAGE_NUM (FLASHPAGE_NUMOF - 0x4)
111#endif
112#define GNRC_LORAWAN_INITIALIZED_MARKER (0x52f94f54U)
113
117#define MHDR_MIC_BUF_SIZE (sizeof(lorawan_hdr_t) + \
118 GNRC_LORAWAN_FOPTS_MAX_SIZE + \
119 GNRC_LORAWAN_FPORT_SIZE + \
120 MIC_SIZE)
121
125typedef struct {
126 uint8_t *data;
127 uint8_t size;
128 uint8_t index;
130
134typedef struct {
135 void *deveui;
136 void *joineui;
137 void *nwkkey;
138#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
139 void *appkey;
140#endif
141 uint8_t dr;
143
153
157typedef struct {
158 uint8_t margin;
159 uint8_t num_gateways;
161
165typedef struct {
167 uint8_t port;
168 uint8_t dr;
170
174typedef struct {
175 uint32_t fcnt;
176 uint32_t fcnt_down;
177#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
178 uint32_t afcnt_down;
179 uint32_t last_fcnt_down;
180#endif
185 uint8_t redundancy;
188
192typedef struct {
193 uint8_t activation;
195 uint32_t nid;
197 uint8_t dev_nonce[2];
200
204typedef struct {
205 uint8_t *appskey;
206 uint8_t *fnwksintkey;
207 uint8_t *snwksintkey;
208 uint8_t *nwksenckey;
209#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
210 uint8_t *jsintkey;
211 uint8_t *jsenckey;
212#endif
214
217typedef struct {
220 void *mlme_buf;
221 void *mcps_buf;
222 uint8_t *joineui;
224#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
225 bool optneg;
226#endif
228 uint16_t channel_mask;
229 uint32_t toa;
230 int busy;
233 int state;
234 uint8_t dl_settings;
235 uint8_t rx_delay;
237 uint8_t last_dr;
240
244typedef struct {
246 uint8_t dev_nonce[2];
248
261 uint32_t fcnt, uint8_t dir,
262 const uint8_t *appskey);
263
278void gnrc_lorawan_encrypt_fopts(uint8_t *fopts, size_t len,
279 const le_uint32_t *dev_addr, uint32_t fcnt,
280 bool afcnt, uint8_t dir, const uint8_t *key);
281
290void gnrc_lorawan_decrypt_join_accept(const uint8_t *key, uint8_t *pkt,
291 int has_clist, uint8_t *out);
292
304void gnrc_lorawan_generate_session_keys(const uint8_t *join_nonce,
305 const uint8_t *dev_nonce,
306 const uint8_t *joineui,
307 gnrc_lorawan_t *mac);
308
322 const uint8_t *nwkkey,
323 uint8_t *jsintkey,
324 uint8_t *jsenckey);
334int gnrc_lorawan_set_dr(gnrc_lorawan_t *mac, uint8_t datarate);
335
348 int confirmed_data, uint8_t port);
349
358
369
378 size_t size);
379
388void gnrc_lorawan_calculate_join_req_mic(const uint8_t *buf, size_t len,
389 uint8_t *key, le_uint32_t *out);
390
399void gnrc_lorawan_calculate_join_acpt_mic(const uint8_t *buf, size_t len,
400 gnrc_lorawan_t *mac, le_uint32_t *out);
401
411void gnrc_lorawan_calculate_mic_uplink(iolist_t *frame, uint16_t conf_fcnt,
412 gnrc_lorawan_t *mac, le_uint32_t *out);
413
425 uint32_t fcnt, uint16_t conf_fcnt,
426 iolist_t *frame,
427 const uint8_t *snwksintkey,
428 le_uint32_t *out);
429
442size_t gnrc_lorawan_build_hdr(uint8_t mtype, le_uint32_t *dev_addr,
443 uint32_t fcnt, uint8_t ack, uint8_t fopts_length,
444 lorawan_buffer_t *buf);
445
454 size_t size);
455
464
473
482void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, iolist_t *psdu, uint8_t dr,
483 uint32_t chan);
484
493 size_t size);
494
504
511
518
528uint8_t gnrc_lorawan_region_mac_payload_max(uint8_t datarate);
529
539
549
558
566
576{
577 int _c = mac->busy;
578
579 mac->busy = true;
580 return !_c;
581}
582
589{
590 mac->busy = false;
591}
592
599void gnrc_lorawan_set_rx2_dr(gnrc_lorawan_t *mac, uint8_t rx2_dr);
600
607
613void gnrc_lorawan_store_dev_nonce(uint8_t *dev_nonce);
614
628static inline bool gnrc_lorawan_optneg_is_set(const gnrc_lorawan_t *mac)
629{
630 (void)mac;
631#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
632 return mac->optneg;
633#else
634 return 1; /* NO-OP */
635#endif
636}
637
650static inline void gnrc_lorawan_set_optneg(gnrc_lorawan_t *mac, uint8_t optneg)
651{
652 (void)mac;
653 (void)optneg;
654
655#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
656 mac->optneg = optneg;
657#endif
658}
659
669static inline uint8_t *gnrc_lorawan_get_jsintkey(const gnrc_lorawan_t *mac)
670{
671 (void)mac;
672#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
673 return mac->ctx.jsintkey;
674#else
675 return NULL; /* NO-OP */
676#endif
677}
678
688static inline uint8_t *gnrc_lorawan_get_jsenckey(const gnrc_lorawan_t *mac)
689{
690 (void)mac;
691#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
692 return mac->ctx.jsenckey;
693#else
694 return NULL; /* NO-OP */
695#endif
696}
697
707static inline uint32_t gnrc_lorawan_get_afcnt_down(const gnrc_lorawan_t *mac)
708{
709 (void)mac;
710#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
711 return mac->mcps.afcnt_down;
712#else
713 return 0; /* NO-OP */
714#endif
715}
716
726static inline void gnrc_lorawan_set_afcnt_down(gnrc_lorawan_t *mac, uint32_t afcnt_down)
727{
728 (void)mac;
729 (void)afcnt_down;
730
731#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
732 mac->mcps.afcnt_down = afcnt_down;
733#endif
734}
735
744static inline uint32_t gnrc_lorawan_get_last_fcnt_down(const gnrc_lorawan_t *mac)
745{
746 (void)mac;
747#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
748 return mac->mcps.last_fcnt_down;
749#else
750 return 0; /* NO-OP */
751#endif
752}
753
763static inline void gnrc_lorawan_set_last_fcnt_down(gnrc_lorawan_t *mac, uint32_t last_fcnt_down)
764{
765 (void)mac;
766 (void)last_fcnt_down;
767#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
768 mac->mcps.last_fcnt_down = last_fcnt_down;
769#endif
770}
771
781static inline uint8_t * gnrc_lorawan_mlme_join_get_appkey(const mlme_lorawan_join_t *mlme_join)
782{
783 (void)mlme_join;
784
785#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
786 return mlme_join->appkey;
787#else
788 return NULL; /* NO-OP */
789#endif
790}
791
801static inline void gnrc_lorawan_mlme_join_set_appkey(mlme_lorawan_join_t *mlme_join, uint8_t *key)
802{
803 (void)mlme_join;
804 (void)key;
805
806#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
807 mlme_join->appkey = key;
808#endif
809}
810
811#ifdef __cplusplus
812}
813#endif
814
Definitions low-level network driver interface.
void gnrc_lorawan_mcps_process_downlink(gnrc_lorawan_t *mac, uint8_t *psdu, size_t size)
Process an MCPS downlink message (confirmable or non comfirmable)
static uint32_t gnrc_lorawan_get_afcnt_down(const gnrc_lorawan_t *mac)
Get the application downlink frame counter from the MAC descriptor.
void gnrc_lorawan_reset(gnrc_lorawan_t *mac)
Reset MAC parameters.
void gnrc_lorawan_perform_save(gnrc_lorawan_t *mac)
save internal MAC state in non-volatile storage and shutdown the MAC layer gracefully.
uint8_t gnrc_lorawan_build_options(gnrc_lorawan_t *mac, lorawan_buffer_t *buf)
Build fopts header.
void gnrc_lorawan_mlme_backoff_expire_cb(gnrc_lorawan_t *mac)
MLME Backoff expiration tick.
static uint8_t * gnrc_lorawan_get_jsintkey(const gnrc_lorawan_t *mac)
Get the join session integrity key from the MAC descriptor.
void gnrc_lorawan_process_fopts(gnrc_lorawan_t *mac, uint8_t *fopts, size_t size)
Process an fopts frame.
void gnrc_lorawan_mlme_no_rx(gnrc_lorawan_t *mac)
Inform the MAC layer that no packet was received during reception.
void gnrc_lorawan_calculate_mic_uplink(iolist_t *frame, uint16_t conf_fcnt, gnrc_lorawan_t *mac, le_uint32_t *out)
Calculate Message Integrity Code for an uplink MCPS message.
static uint8_t * gnrc_lorawan_get_jsenckey(const gnrc_lorawan_t *mac)
Get the join session encryption key from the MAC descriptor.
static void gnrc_lorawan_set_afcnt_down(gnrc_lorawan_t *mac, uint32_t afcnt_down)
Set the application downlink frame counter in the MAC descriptor.
size_t gnrc_lorawan_build_uplink(gnrc_lorawan_t *mac, iolist_t *payload, int confirmed_data, uint8_t port)
build uplink frame
static void gnrc_lorawan_set_last_fcnt_down(gnrc_lorawan_t *mac, uint32_t last_fcnt_down)
Set the last downlink frame counter in the MAC descriptor.
static void gnrc_lorawan_mlme_join_set_appkey(mlme_lorawan_join_t *mlme_join, uint8_t *key)
Se the app key in the MLME join request data.
void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, iolist_t *psdu, uint8_t dr, uint32_t chan)
Send a LoRaWAN packet.
void gnrc_lorawan_calculate_join_req_mic(const uint8_t *buf, size_t len, uint8_t *key, le_uint32_t *out)
Calculate join-request Message Integrity Code.
void gnrc_lorawan_mlme_process_join(gnrc_lorawan_t *mac, uint8_t *data, size_t size)
Process join accept message.
void gnrc_lorawan_calculate_join_acpt_mic(const uint8_t *buf, size_t len, gnrc_lorawan_t *mac, le_uint32_t *out)
Calculate join-accept Message Integrity Code.
void gnrc_lorawan_decrypt_join_accept(const uint8_t *key, uint8_t *pkt, int has_clist, uint8_t *out)
Decrypts join accept message.
void gnrc_lorawan_generate_lifetime_session_keys(const uint8_t *deveui, const uint8_t *nwkkey, uint8_t *jsintkey, uint8_t *jsenckey)
Generate LoRaWAN 1.1x lifetime session keys.
size_t gnrc_lorawan_build_hdr(uint8_t mtype, le_uint32_t *dev_addr, uint32_t fcnt, uint8_t ack, uint8_t fopts_length, lorawan_buffer_t *buf)
Build a MCPS LoRaWAN header.
void gnrc_lorawan_store_dev_nonce(uint8_t *dev_nonce)
Store DevNonce in flash memory.
static void gnrc_lorawan_set_optneg(gnrc_lorawan_t *mac, uint8_t optneg)
Set OptNeg bit in the MAC descriptor.
static uint32_t gnrc_lorawan_get_last_fcnt_down(const gnrc_lorawan_t *mac)
Get the last downlink frame counter from the MAC descriptor.
void gnrc_lorawan_open_rx_window(gnrc_lorawan_t *mac)
Open a reception window.
uint8_t gnrc_lorawan_region_mac_payload_max(uint8_t datarate)
Get the maximum MAC payload (M value) for a given datarate.
void gnrc_lorawan_trigger_join(gnrc_lorawan_t *mac)
Trigger the transmission of the Join Request packet.
static int gnrc_lorawan_mac_acquire(gnrc_lorawan_t *mac)
Acquire the MAC layer.
void gnrc_lorawan_generate_session_keys(const uint8_t *join_nonce, const uint8_t *dev_nonce, const uint8_t *joineui, gnrc_lorawan_t *mac)
Generate LoRaWAN session keys.
void gnrc_lorawan_set_rx2_dr(gnrc_lorawan_t *mac, uint8_t rx2_dr)
Set the datarate of the second reception window.
mlme_join_req_type_t
MLME Join Request type.
@ REJOIN_REQ_2
Rejoin-request type 2.
@ JOIN_REQ
Join-request type.
@ REJOIN_REQ_0
Rejoin-request type 0.
@ REJOIN_REQ_1
Rejoin-request type 1.
void gnrc_lorawan_process_pkt(gnrc_lorawan_t *mac, iolist_t *pkt)
Process and dispatch a full LoRaWAN packet.
void gnrc_lorawan_event_retrans_timeout(gnrc_lorawan_t *mac)
Mac callback for retransmission timeout event.
static void gnrc_lorawan_mac_release(gnrc_lorawan_t *mac)
Release the MAC layer.
int gnrc_lorawan_set_dr(gnrc_lorawan_t *mac, uint8_t datarate)
Set datarate for the next transmission.
void gnrc_lorawan_encrypt_fopts(uint8_t *fopts, size_t len, const le_uint32_t *dev_addr, uint32_t fcnt, bool afcnt, uint8_t dir, const uint8_t *key)
Encrypts FOpts field.
static bool gnrc_lorawan_optneg_is_set(const gnrc_lorawan_t *mac)
Check whether OptNeg bit is set.
static uint8_t * gnrc_lorawan_mlme_join_get_appkey(const mlme_lorawan_join_t *mlme_join)
Get the app key from the MLME join request data.
void gnrc_lorawan_event_no_rx(gnrc_lorawan_t *mac)
Mac callback for no RX.
void gnrc_lorawan_channels_init(gnrc_lorawan_t *mac)
Init regional channel settings.
#define MHDR_MIC_BUF_SIZE
Size of the internal MHDR-MIC buffer.
void gnrc_lorawan_encrypt_payload(iolist_t *iolist, const le_uint32_t *dev_addr, uint32_t fcnt, uint8_t dir, const uint8_t *appskey)
Encrypts LoRaWAN payload.
void gnrc_lorawan_calculate_mic_downlink(const le_uint32_t *dev_addr, uint32_t fcnt, uint16_t conf_fcnt, iolist_t *frame, const uint8_t *snwksintkey, le_uint32_t *out)
Calculate Message Integrity Code for downlink MCPS message.
uint8_t gnrc_lorawan_pick_channel(gnrc_lorawan_t *mac)
pick a random available LoRaWAN channel
#define GNRC_LORAWAN_MAX_CHANNELS
Maximum number of channels.
struct iolist iolist_t
iolist forward declaration
Definition iolist.h:30
iolist scatter / gather IO
LoRaMAC header definitions.
LoRaWAN header type and helper function definitions.
Interface definition for the global network buffer.
GNRC LoRaWAN key context struct.
uint8_t * snwksintkey
pointer to Serving Network session integrity key
uint8_t * nwksenckey
pointer to Network session encryption key
uint8_t * appskey
pointer to Application SKey buffer
uint8_t * fnwksintkey
pointer to Forwarding Network session integrity key
MCPS service access point descriptor.
int ack_requested
whether the network server requested an ACK
iolist_t * msdu
current MSDU
uint32_t fcnt
uplink framecounter
char mhdr_mic[MHDR_MIC_BUF_SIZE]
internal retransmissions buffer
int waiting_for_ack
true if the MAC layer is waiting for an ACK
uint32_t fcnt_down
downlink frame counter.
int nb_trials
holds the remaining number of retransmissions
uint8_t redundancy
unconfirmed uplink redundancy
MLME service access point descriptor.
uint8_t backoff_state
state in the backoff state machine
uint8_t activation
Activation mechanism of the MAC layer.
uint8_t dev_nonce[2]
Device Nonce.
int pending_mlme_opts
holds pending mlme opts
uint32_t nid
current Network ID
int32_t backoff_budget
remaining Time On Air budget
LoRaWAN state that needs to be preserved across reboots.
uint32_t initialized_marker
state initialized marker
GNRC LoRaWAN mac descriptor.
void * mlme_buf
pointer to MLME buffer
uint32_t channel[GNRC_LORAWAN_MAX_CHANNELS]
channel array
uint8_t rx_delay
Delay of first reception window.
uint8_t dr_range[GNRC_LORAWAN_MAX_CHANNELS]
Datarate Range for all channels.
uint8_t * joineui
pointer to Join EUI
int shutdown_req
MAC Shutdown request.
uint8_t last_dr
datarate of the last transmission
uint8_t last_chan_idx
index of channel used for last transmission
int state
state of MAC layer
void * mcps_buf
pointer to MCPS buffer
le_uint32_t dev_addr
Device address.
uint8_t dl_settings
downlink settings
uint32_t toa
Time on Air of the last transmission.
gnrc_lorawan_mlme_t mlme
MLME descriptor.
uint16_t channel_mask
channel mask
gnrc_lorawan_mcps_t mcps
MCPS descriptor.
gnrc_lorawan_key_ctx_t ctx
GNRC LoRaWAN key context struct.
iolist structure definition
Definition iolist.h:35
buffer helper for parsing and constructing LoRaWAN packets.
uint8_t * data
pointer to the beginning of the buffer holding data
uint8_t size
size of the buffer
uint8_t index
current index in the buffer
uint8_t port
port of the request
uint8_t dr
datarate of the request
iolist_t * pkt
packet of the request
MLME Join Request data.
void * joineui
pointer to the Join EUI
uint8_t dr
datarate for the Join Request
void * deveui
pointer to the Device EUI
void * nwkkey
pointer to the Network Key.
LoRa modulation header definitions.
A 32 bit integer in little endian.
Definition byteorder.h:44