18#ifndef GNRC_LORAWAN_INTERNAL_H
19#define GNRC_LORAWAN_INTERNAL_H
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
47#define MAJOR_LRWAN_R1 0x0
49#define MINOR_LRWAN 0x1
51#define JOIN_REQUEST_SIZE (23U)
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)
113#define GNRC_LORAWAN_STATE_FLASHPAGE_NUM (FLASHPAGE_NUMOF - 0x4)
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 + \
141#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
180#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
182 uint32_t last_fcnt_down;
200 uint8_t dev_nonce[2];
212#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
227#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
249 uint8_t dev_nonce[2];
264 uint32_t fcnt, uint8_t dir,
265 const uint8_t *appskey);
283 bool afcnt, uint8_t dir,
const uint8_t *key);
294 int has_clist, uint8_t *out);
308 const uint8_t *dev_nonce,
309 const uint8_t *joineui,
325 const uint8_t *nwkkey,
351 int confirmed_data, uint8_t port);
428 uint32_t fcnt, uint16_t conf_fcnt,
430 const uint8_t *snwksintkey,
446 uint32_t fcnt, uint8_t ack, uint8_t fopts_length,
634#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
658#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
659 mac->optneg = optneg;
675#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
676 return mac->
ctx.jsintkey;
694#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
695 return mac->
ctx.jsenckey;
713#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
714 return mac->
mcps.afcnt_down;
734#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
735 mac->
mcps.afcnt_down = afcnt_down;
750#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
751 return mac->
mcps.last_fcnt_down;
769 (void)last_fcnt_down;
770#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
771 mac->
mcps.last_fcnt_down = last_fcnt_down;
788#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
789 return mlme_join->appkey;
809#if IS_USED(MODULE_GNRC_LORAWAN_1_1)
810 mlme_join->appkey = key;
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
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 Link Check confirmation data.
uint8_t num_gateways
number of gateways
uint8_t margin
demodulation margin (in dB)
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.