1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/sys/include/net/lorawan/hdr.h

302 lines
9.3 KiB
C

/*
* Copyright (C) 2016 Fundación Inria Chile
* Copyright (C) 2019 HAW Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_lorawan_hdr LoRaWAN header
* @ingroup net_lorawan
* @brief LoRaWAN header types and helper functions
* @{
*
* @file
* @brief LoRaWAN header type and helper function definitions
*
* @author Jose Ignacio Alamos <jose.alamos@haw-hamburg.de>
*/
#ifndef NET_LORAWAN_HDR_H
#define NET_LORAWAN_HDR_H
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "byteorder.h"
#include "net/loramac.h"
#define LORAWAN_HDR_MTYPE_MASK (0xe0) /**< MType mask */
#define LORAWAN_HDR_MTYPE_POS (5U) /**< MType position */
#define LORAWAN_HDR_MAJOR_MASK (0x03) /**< Major version mask */
#define LORAWAN_HDR_MAJOR_POS (0U) /**< Major version position */
#define LORAWAN_HDR_ADR_MASK (0x80) /**< ADR mask */
#define LORAWAN_HDR_ADR_POS (7U) /**< ADR position */
#define LORAWAN_HDR_ADR_ACK_MASK (0x40) /**< ADR ACK bit mask */
#define LORAWAN_HDR_ADR_ACK_POS (6U) /**< ADR ACK bit position */
#define LORAWAN_HDR_ACK_MASK (0x20) /**< ACK bit mask */
#define LORAWAN_HDR_ACK_POS (5U) /**< ACK bit position */
#define LORAWAN_HDR_FRAME_PENDING_MASK (0x10) /**< Frame pending bit mask */
#define LORAWAN_HDR_FRAME_PENDING_POS (4U) /**< Frame pending bit position */
#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
/**
* @brief Data type to represent a LoRaWAN packet header
*
* This definition includes MHDR and FHDR in the same structure.
* The structure of the header is as follows:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.unparsed}
* 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
* |Mtype| RFU |Maj| LoRaWAN Address ...
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* ... | Frame Control | Frame Counter |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @see <a href="https://lora-alliance.org/sites/default/files/2018-07/lorawan1.0.3.pdf">
* LoRaWAN spcefication, section 4
* </a>
*/
typedef struct __attribute__((packed)) {
/**
* @brief message type and major version
*
* The message type are the 3 most significant bytes and the
* major version are the 2 less significant bytes. There are 3 bytes
* in the middle reserved for future usage.
* This module provides helper functions to set and get:
* * lorawan_hdr_set_mtype()
* * lorawan_hdr_get_mtype()
* * lorawan_hdr_set_maj()
* * lorawan_hdr_get_maj()
*/
uint8_t mt_maj;
le_uint32_t addr; /**< 32 bit LoRaWAN address */
uint8_t fctrl; /**< frame control */
le_uint16_t fcnt; /**< frame counter */
} lorawan_hdr_t;
/**
* @brief Join request packet representation
*/
typedef struct __attribute__((packed)) {
uint8_t mt_maj; /**< mtype and major version holder */
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 */
} lorawan_join_request_t;
/**
* @brief Join accept packet representation
*/
typedef struct __attribute__((packed)) {
uint8_t mt_maj; /**< mtype and major version holder */
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 */
uint8_t rx_delay; /**< first reception window delay */
} lorawan_join_accept_t;
/**
* @brief Set LoRaWAN header MType
*
* @param[in] hdr LoRaWAN hdr
* @param[in] mtype desired MType
*/
static inline void lorawan_hdr_set_mtype(lorawan_hdr_t *hdr, uint8_t mtype)
{
hdr->mt_maj &= ~LORAWAN_HDR_MTYPE_MASK;
hdr->mt_maj |= (mtype << LORAWAN_HDR_MTYPE_POS) & LORAWAN_HDR_MTYPE_MASK;
}
/**
* @brief Get LoRaWAN header MType
*
* @param[in] hdr LoRaWAN hdr
*
* @return mtype of the packet
*/
static inline uint8_t lorawan_hdr_get_mtype(lorawan_hdr_t *hdr)
{
return ((hdr->mt_maj & LORAWAN_HDR_MTYPE_MASK) >> LORAWAN_HDR_MTYPE_POS);
}
/**
* @brief Set LoRaWAN major version
*
* @param[in] hdr LoRaWAN header
* @param[in] maj major version
*/
static inline void lorawan_hdr_set_maj(lorawan_hdr_t *hdr, uint8_t maj)
{
hdr->mt_maj &= ~LORAWAN_HDR_MAJOR_MASK;
hdr->mt_maj |= (maj << LORAWAN_HDR_MAJOR_POS) & LORAWAN_HDR_MAJOR_MASK;
}
/**
* @brief Get LoRaWAN major version
*
* @param[in] hdr LoRaWAN header
*
* @return major version of the packet
*/
static inline uint8_t lorawan_hdr_get_maj(lorawan_hdr_t *hdr)
{
return (hdr->mt_maj & LORAWAN_HDR_MAJOR_MASK) >> LORAWAN_HDR_MAJOR_POS;
}
/**
* @brief Set LoRaWAN header Adaptive Data Rate bit
*
* @param[in] hdr LoRaWAN header
* @param[in] adr value of the ADR bit
*/
static inline void lorawan_hdr_set_adr(lorawan_hdr_t *hdr, bool adr)
{
hdr->fctrl &= ~LORAWAN_HDR_ADR_MASK;
hdr->fctrl |= (adr << LORAWAN_HDR_ADR_POS) & LORAWAN_HDR_ADR_MASK;
}
/**
* @brief Get LoRaWAN header Adaptive Data Rate bit
*
* @param[in] hdr LoRaWAN header
*
* @return the value of the ADR bit
*/
static inline bool lorawan_hdr_get_adr(lorawan_hdr_t *hdr)
{
return (hdr->fctrl & LORAWAN_HDR_ADR_MASK) >> LORAWAN_HDR_ADR_POS;
}
/**
* @brief Set LoRaWAN header ADR ACK request bit
*
* @param[in] hdr LoRaWAN header
* @param[in] adr_ack_req value of the ADR ACK request bit
*/
static inline void lorawan_hdr_set_adr_ack_req(lorawan_hdr_t *hdr, bool adr_ack_req)
{
hdr->fctrl &= ~LORAWAN_HDR_ADR_ACK_MASK;
hdr->fctrl |= (adr_ack_req << LORAWAN_HDR_ADR_ACK_POS) & LORAWAN_HDR_ADR_ACK_MASK;
}
/**
* @brief Get LoRaWAN header ADR ACK request bit
*
* @param[in] hdr LoRaWAN header
*
* @return the value of ADR ACK request bit
*/
static inline bool lorawan_hdr_get_adr_ack_req(lorawan_hdr_t *hdr)
{
return (hdr->fctrl & LORAWAN_HDR_ADR_ACK_MASK) >> LORAWAN_HDR_ADR_ACK_POS;
}
/**
* @brief Set LoRaWAN header ACK bit
*
* @param[in] hdr LoRaWAN header
* @param[in] ack value of the ACK bit
*/
static inline void lorawan_hdr_set_ack(lorawan_hdr_t *hdr, bool ack)
{
hdr->fctrl &= ~LORAWAN_HDR_ACK_MASK;
hdr->fctrl |= (ack << LORAWAN_HDR_ACK_POS) & LORAWAN_HDR_ACK_MASK;
}
/**
* @brief Get LoRaWAN header ACK bit
*
* @param[in] hdr LoRaWAN header
*
* @return value of the ACK bit
*/
static inline bool lorawan_hdr_get_ack(lorawan_hdr_t *hdr)
{
return (hdr->fctrl & LORAWAN_HDR_ACK_MASK) >> LORAWAN_HDR_ACK_POS;
}
/**
* @brief Set LoRaWAN header frame pending bit
*
* @param[in] hdr LoRaWAN header
* @param[in] frame_pending value of the frame pending bit
*/
static inline void lorawan_hdr_set_frame_pending(lorawan_hdr_t *hdr, bool frame_pending)
{
hdr->fctrl &= ~LORAWAN_HDR_FRAME_PENDING_MASK;
hdr->fctrl |= (frame_pending << LORAWAN_HDR_FRAME_PENDING_POS) & LORAWAN_HDR_FRAME_PENDING_MASK;
}
/**
* @brief Get LoRaWAN header frame pending bit
*
* @param[in] hdr LoRaWAN header
*
* @return value of the frame pending bit
*/
static inline bool lorawan_hdr_get_frame_pending(lorawan_hdr_t *hdr)
{
return (hdr->fctrl & LORAWAN_HDR_FRAME_PENDING_MASK) >> LORAWAN_HDR_FRAME_PENDING_POS;
}
/**
* @brief Set LoRaWAN header FOpts length
*
* @param[in] hdr LoRaWAN header
* @param[in] len length of the piggybacked FOpts
*/
static inline void lorawan_hdr_set_frame_opts_len(lorawan_hdr_t *hdr, uint8_t len)
{
hdr->fctrl &= ~LORAWAN_HDR_FOPTS_LEN_MASK;
hdr->fctrl |= (len << LORAWAN_HDR_FOPTS_LEN_POS) & LORAWAN_HDR_FOPTS_LEN_MASK;
}
/**
* @brief Get LoRaWAN header FOps length
*
* @param[in] hdr LoRaWAN header
*
* @return length of piggybacked FOpts
*/
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
#endif /* NET_LORAWAN_HDR_H */
/** @} */