Loading...
Searching...
No Matches
gnrc_lorawan_internal.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2019 HAW Hamburg
3 *
4 * This file is subject to the terms and conditions of the GNU Lesser
5 * General Public License v2.1. See the file LICENSE in the top level
6 * directory for more details.
7 */
8
18#ifndef GNRC_LORAWAN_INTERNAL_H
19#define GNRC_LORAWAN_INTERNAL_H
20
21#include <stdio.h>
22#include <string.h>
23#include "iolist.h"
24#include "net/lora.h"
25#include "net/lorawan/hdr.h"
26#include "net/gnrc/pktbuf.h"
27#include "net/netdev.h"
28#include "net/loramac.h"
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34#define MSG_TYPE_TIMEOUT (0x3457)
36#define MTYPE_MASK 0xE0
37#define MTYPE_JOIN_REQUEST 0x0
38#define MTYPE_JOIN_ACCEPT 0x1
39#define MTYPE_UNCNF_UPLINK 0x2
40#define MTYPE_UNCNF_DOWNLINK 0x3
41#define MTYPE_CNF_UPLINK 0x4
42#define MTYPE_CNF_DOWNLINK 0x5
43#define MTYPE_REJOIN_REQ 0x6
44#define MTYPE_PROPIETARY 0x7
46#define MAJOR_MASK 0x3
47#define MAJOR_LRWAN_R1 0x0
49#define MINOR_LRWAN 0x1
51#define JOIN_REQUEST_SIZE (23U)
52#define MIC_SIZE (4U)
53#define CFLIST_SIZE (16U)
55#define GNRC_LORAWAN_MAX_CHANNELS (16U)
57#define LORAWAN_STATE_IDLE (0)
58#define LORAWAN_STATE_RX_1 (1)
59#define LORAWAN_STATE_RX_2 (2)
60#define LORAWAN_STATE_TX (3)
61#define LORAWAN_STATE_JOIN (4)
63#define GNRC_LORAWAN_DIR_UPLINK (0U)
64#define GNRC_LORAWAN_DIR_DOWNLINK (1U)
66#define GNRC_LORAWAN_BACKOFF_WINDOW_TICK (3600000000LL)
68#define GNRC_LORAWAN_BACKOFF_BUDGET_1 (36000000LL)
69#define GNRC_LORAWAN_BACKOFF_BUDGET_2 (36000000LL)
70#define GNRC_LORAWAN_BACKOFF_BUDGET_3 (8700000LL)
72#define GNRC_LORAWAN_MLME_OPTS_LINK_CHECK_REQ (1 << 0)
73#define GNRC_LORAWAN_MLME_OPTS_REKEY_IND_REQ (1 << 1)
75#define GNRC_LORAWAN_CID_SIZE (1U)
76#define GNRC_LORAWAN_CID_LINK_CHECK_ANS (0x02)
78#define GNCR_LORAWAN_REKEY_IND_SIZE (1U)
79#define GNCR_LORAWAN_CID_REKEY_CONF (0x0B)
81#define GNRC_LORAWAN_FOPT_LINK_CHECK_ANS_SIZE (3U)
82#define GNRC_LORAWAN_FOPT_REKEY_CONF_SIZE (2U)
84#define GNRC_LORAWAN_JOIN_DELAY_U32_MASK (0x1FFFFF)
86#define GNRC_LORAWAN_MAX_PAYLOAD_1 (59U)
87#define GNRC_LORAWAN_MAX_PAYLOAD_2 (123U)
88#define GNRC_LORAWAN_MAX_PAYLOAD_3 (250U)
90#define GNRC_LORAWAN_CFLIST_ENTRY_SIZE (3U)
91#define GNRC_LORAWAN_JOIN_ACCEPT_MAX_SIZE (33U)
93#define GNRC_LORAWAN_BACKOFF_STATE_1 (0U)
94#define GNRC_LORAWAN_BACKOFF_STATE_2 (1U)
95#define GNRC_LORAWAN_BACKOFF_STATE_3 (2U)
97#define GNRC_LORAWAN_BACKOFF_TIME_1 (1U)
98#define GNRC_LORAWAN_BACKOFF_TIME_2 (10U)
99#define GNRC_LORAWAN_BACKOFF_TIME_3 (24U)
101#define GNRC_LORAWAN_APP_NONCE_SIZE (3U)
102#define GNRC_LORAWAN_JOIN_NONCE_SIZE (3U)
103#define GNRC_LORAWAN_NET_ID_SIZE (3U)
104#define GNRC_LORAWAN_DEV_NONCE_SIZE (2U)
106#define GNRC_LORAWAN_FOPTS_MAX_SIZE (15U)
107#define GNRC_LORAWAN_FPORT_SIZE (1U)
109#if defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) || \
110 defined(CPU_FAM_STM32F7)
111#define GNRC_LORAWAN_STATE_FLASHPAGE_NUM (0x7)
112#else
113#define GNRC_LORAWAN_STATE_FLASHPAGE_NUM (FLASHPAGE_NUMOF - 0x4)
114#endif
115#define GNRC_LORAWAN_INITIALIZED_MARKER (0x52f94f54U)
120#define MHDR_MIC_BUF_SIZE (sizeof(lorawan_hdr_t) + \
121 GNRC_LORAWAN_FOPTS_MAX_SIZE + \
122 GNRC_LORAWAN_FPORT_SIZE + \
123 MIC_SIZE)
124
128typedef struct {
129 uint8_t *data;
130 uint8_t size;
131 uint8_t index;
133
137typedef struct {
138 void *deveui;
139 void *joineui;
140 void *nwkkey;
141#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
142 void *appkey;
143#endif
144 uint8_t dr;
146
156
160typedef struct {
161 uint8_t margin;
162 uint8_t num_gateways;
164
168typedef struct {
170 uint8_t port;
171 uint8_t dr;
173
177typedef struct {
178 uint32_t fcnt;
179 uint32_t fcnt_down;
180#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
181 uint32_t afcnt_down;
182 uint32_t last_fcnt_down;
183#endif
188 uint8_t redundancy;
189 char mhdr_mic[MHDR_MIC_BUF_SIZE];
191
195typedef struct {
196 uint8_t activation;
198 uint32_t nid;
200 uint8_t dev_nonce[2];
203
207typedef struct {
208 uint8_t *appskey;
209 uint8_t *fnwksintkey;
210 uint8_t *snwksintkey;
211 uint8_t *nwksenckey;
212#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
213 uint8_t *jsintkey;
214 uint8_t *jsenckey;
215#endif
217
220typedef struct {
223 void *mlme_buf;
224 void *mcps_buf;
225 uint8_t *joineui;
227#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
228 bool optneg;
229#endif
230 uint32_t channel[GNRC_LORAWAN_MAX_CHANNELS];
231 uint16_t channel_mask;
232 uint32_t toa;
233 int busy;
236 int state;
237 uint8_t dl_settings;
238 uint8_t rx_delay;
239 uint8_t dr_range[GNRC_LORAWAN_MAX_CHANNELS];
240 uint8_t last_dr;
243
247typedef struct {
249 uint8_t dev_nonce[2];
251
264 uint32_t fcnt, uint8_t dir,
265 const uint8_t *appskey);
266
281void gnrc_lorawan_encrypt_fopts(uint8_t *fopts, size_t len,
282 const le_uint32_t *dev_addr, uint32_t fcnt,
283 bool afcnt, uint8_t dir, const uint8_t *key);
284
293void gnrc_lorawan_decrypt_join_accept(const uint8_t *key, uint8_t *pkt,
294 int has_clist, uint8_t *out);
295
307void gnrc_lorawan_generate_session_keys(const uint8_t *join_nonce,
308 const uint8_t *dev_nonce,
309 const uint8_t *joineui,
310 gnrc_lorawan_t *mac);
311
325 const uint8_t *nwkkey,
326 uint8_t *jsintkey,
327 uint8_t *jsenckey);
337int gnrc_lorawan_set_dr(gnrc_lorawan_t *mac, uint8_t datarate);
338
351 int confirmed_data, uint8_t port);
352
361
372
381 size_t size);
382
391void gnrc_lorawan_calculate_join_req_mic(const uint8_t *buf, size_t len,
392 uint8_t *key, le_uint32_t *out);
393
402void gnrc_lorawan_calculate_join_acpt_mic(const uint8_t *buf, size_t len,
403 gnrc_lorawan_t *mac, le_uint32_t *out);
404
414void gnrc_lorawan_calculate_mic_uplink(iolist_t *frame, uint16_t conf_fcnt,
415 gnrc_lorawan_t *mac, le_uint32_t *out);
416
428 uint32_t fcnt, uint16_t conf_fcnt,
429 iolist_t *frame,
430 const uint8_t *snwksintkey,
431 le_uint32_t *out);
432
445size_t gnrc_lorawan_build_hdr(uint8_t mtype, le_uint32_t *dev_addr,
446 uint32_t fcnt, uint8_t ack, uint8_t fopts_length,
447 lorawan_buffer_t *buf);
448
457 size_t size);
458
467
476
485void gnrc_lorawan_send_pkt(gnrc_lorawan_t *mac, iolist_t *psdu, uint8_t dr,
486 uint32_t chan);
487
496 size_t size);
497
507
514
521
531uint8_t gnrc_lorawan_region_mac_payload_max(uint8_t datarate);
532
542
552
561
569
579{
580 int _c = mac->busy;
581
582 mac->busy = true;
583 return !_c;
584}
585
592{
593 mac->busy = false;
594}
595
602void gnrc_lorawan_set_rx2_dr(gnrc_lorawan_t *mac, uint8_t rx2_dr);
603
610
616void gnrc_lorawan_store_dev_nonce(uint8_t *dev_nonce);
617
631static inline bool gnrc_lorawan_optneg_is_set(const gnrc_lorawan_t *mac)
632{
633 (void)mac;
634#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
635 return mac->optneg;
636#else
637 return 1; /* NO-OP */
638#endif
639}
640
653static inline void gnrc_lorawan_set_optneg(gnrc_lorawan_t *mac, uint8_t optneg)
654{
655 (void)mac;
656 (void)optneg;
657
658#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
659 mac->optneg = optneg;
660#endif
661}
662
672static inline uint8_t *gnrc_lorawan_get_jsintkey(const gnrc_lorawan_t *mac)
673{
674 (void)mac;
675#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
676 return mac->ctx.jsintkey;
677#else
678 return NULL; /* NO-OP */
679#endif
680}
681
691static inline uint8_t *gnrc_lorawan_get_jsenckey(const gnrc_lorawan_t *mac)
692{
693 (void)mac;
694#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
695 return mac->ctx.jsenckey;
696#else
697 return NULL; /* NO-OP */
698#endif
699}
700
710static inline uint32_t gnrc_lorawan_get_afcnt_down(const gnrc_lorawan_t *mac)
711{
712 (void)mac;
713#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
714 return mac->mcps.afcnt_down;
715#else
716 return 0; /* NO-OP */
717#endif
718}
719
729static inline void gnrc_lorawan_set_afcnt_down(gnrc_lorawan_t *mac, uint32_t afcnt_down)
730{
731 (void)mac;
732 (void)afcnt_down;
733
734#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
735 mac->mcps.afcnt_down = afcnt_down;
736#endif
737}
738
747static inline uint32_t gnrc_lorawan_get_last_fcnt_down(const gnrc_lorawan_t *mac)
748{
749 (void)mac;
750#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
751 return mac->mcps.last_fcnt_down;
752#else
753 return 0; /* NO-OP */
754#endif
755}
756
766static inline void gnrc_lorawan_set_last_fcnt_down(gnrc_lorawan_t *mac, uint32_t last_fcnt_down)
767{
768 (void)mac;
769 (void)last_fcnt_down;
770#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
771 mac->mcps.last_fcnt_down = last_fcnt_down;
772#endif
773}
774
784static inline uint8_t * gnrc_lorawan_mlme_join_get_appkey(const mlme_lorawan_join_t *mlme_join)
785{
786 (void)mlme_join;
787
788#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
789 return mlme_join->appkey;
790#else
791 return NULL; /* NO-OP */
792#endif
793}
794
804static inline void gnrc_lorawan_mlme_join_set_appkey(mlme_lorawan_join_t *mlme_join, uint8_t *key)
805{
806 (void)mlme_join;
807 (void)key;
808
809#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
810 mlme_join->appkey = key;
811#endif
812}
813
814#ifdef __cplusplus
815}
816#endif
817
818#endif /* GNRC_LORAWAN_INTERNAL_H */
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.
iolist scatter / gather IO
LoRaMAC header definitions.
LoRaWAN header type and helper function definitions.
Interface definition for the global network buffer.
stdio wrapper to extend the C libs stdio
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
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.
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
uint8_t rx_delay
Delay of first reception window.
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:39
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:48