diff --git a/sys/include/net/gnrc/lorawan.h b/sys/include/net/gnrc/lorawan.h new file mode 100644 index 0000000000..3c321b9cb4 --- /dev/null +++ b/sys/include/net/gnrc/lorawan.h @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2017 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_gnrc_lorawan GNRC LoRaWAN + * @ingroup net_gnrc + * @brief GNRC LoRaWAN stack implementation + * + * @{ + * + * @file + * @brief GNRC LoRaWAN API definition + * + * @author José Ignacio Alamos + * @author Francisco Molina + */ +#ifndef NET_GNRC_LORAWAN_H +#define NET_GNRC_LORAWAN_H + +#include "gnrc_lorawan_internal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief maximum timer drift in percentage + * + * @note this is only a workaround to compensate inaccurate timers. + * + * E.g a value of 0.1 means there's a positive drift of 0.1% (set timeout to + * 1000 ms => triggers after 1001 ms) + */ +#ifndef CONFIG_GNRC_LORAWAN_TIMER_DRIFT +#define CONFIG_GNRC_LORAWAN_TIMER_DRIFT 1 +#endif + +/** + * @brief the minimum symbols to detect a LoRa preamble + */ +#ifndef CONFIG_GNRC_LORAWAN_MIN_SYMBOLS_TIMEOUT +#define CONFIG_GNRC_LORAWAN_MIN_SYMBOLS_TIMEOUT 30 +#endif + +#define GNRC_LORAWAN_REQ_STATUS_SUCCESS (0) /**< MLME or MCPS request successful status */ +#define GNRC_LORAWAN_REQ_STATUS_DEFERRED (1) /**< the MLME or MCPS confirm message is asynchronous */ + +/** + * @brief MCPS events + */ +typedef enum { + MCPS_EVENT_RX, /**< MCPS RX event */ + MCPS_EVENT_NO_RX, /**< MCPS no RX event */ + MCPS_EVENT_ACK_TIMEOUT /**< MCPS retrans event */ +} mcps_event_t; + +/** + * @brief LoRaWAN activation mechanism + */ +typedef enum { + MLME_ACTIVATION_NONE, /**< MAC layer is not activated */ + MLME_ACTIVATION_ABP, /**< MAC layer activated by ABP */ + MLME_ACTIVATION_OTAA /**< MAC layer activated by OTAA */ +} mlme_activation_t; + +/** + * @brief MAC Information Base attributes + */ +typedef enum { + MIB_ACTIVATION_METHOD /**< type is activation method */ +} mlme_mib_type_t; + +/** + * @brief MLME primitive types + */ +typedef enum { + MLME_JOIN, /**< join a LoRaWAN network */ + MLME_LINK_CHECK, /**< perform a Link Check */ + MLME_RESET, /**< reset the MAC layer */ + MLME_SET, /**< set the MIB */ + MLME_GET, /**< get the MIB */ + MLME_SCHEDULE_UPLINK /**< schedule uplink indication */ +} mlme_type_t; + +/** + * @brief MCPS primitive types + */ +typedef enum { + MCPS_CONFIRMED, /**< confirmed data */ + MCPS_UNCONFIRMED /**< unconfirmed data */ +} mcps_type_t; + +/** + * @brief MAC Information Base descriptor for MLME Request-Confirm + */ +typedef struct { + mlme_mib_type_t type; /**< MIB attribute identifier */ + union { + mlme_activation_t activation; /**< holds activation mechanism */ + }; +} mlme_mib_t; + +/** + * @brief MAC (sub) Layer Management Entity (MLME) request representation + */ +typedef struct { + union { + mlme_lorawan_join_t join; /**< Join Data holder */ + mlme_mib_t mib; /**< MIB holder */ + }; + mlme_type_t type; /**< type of the MLME request */ +} mlme_request_t; + +/** + * @brief Mac Common Part Sublayer (MCPS) request representation + */ +typedef struct { + union { + mcps_data_t data; /**< MCPS data holder */ + }; + mcps_type_t type; /**< type of the MCPS request */ +} mcps_request_t; + +/** + * @brief MAC (sub) Layer Management Entity (MLME) confirm representation + */ +typedef struct { + int16_t status; /**< status of the MLME confirm */ + mlme_type_t type; /**< type of the MLME confirm */ + union { + mlme_link_req_confirm_t link_req; /**< Link Check confirmation data */ + mlme_mib_t mib; /**< MIB confirmation data */ + }; +} mlme_confirm_t; + +/** + * @brief Mac Common Part Sublayer (MCPS) confirm representation + */ +typedef struct { + void *data; /**< data of the MCPS confirm */ + int16_t status; /**< status of the MCPS confirm */ + mcps_type_t type; /**< type of the MCPS confirm */ +} mcps_confirm_t; + +/** + * @brief Mac Common Part Sublayer (MCPS) indication representation + */ +typedef struct { + mcps_type_t type; /**< type of the MCPS indication */ + union { + mcps_data_t data; /**< MCPS Data holder */ + }; +} mcps_indication_t; + +/** + * @brief MAC (sub) Layer Management Entity (MLME) indication representation + */ +typedef struct { + mlme_type_t type; /**< type of the MLME indication */ +} mlme_indication_t; + +/** + * @brief Indicate the MAC layer there was a timeout event + * + * @param[in] mac pointer to the MAC descriptor + */ +void gnrc_lorawan_event_timeout(gnrc_lorawan_t *mac); + +/** + * @brief Indicate the MAC layer when the transmission finished + * + * @param[in] mac pointer to the MAC descriptor + */ +void gnrc_lorawan_event_tx_complete(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 + */ +void gnrc_lorawan_init(gnrc_lorawan_t *mac, uint8_t *nwkskey, uint8_t *appskey); + +/** + * @brief Perform a MLME request + * + * @param[in] mac pointer to the MAC descriptor + * @param[in] mlme_request the MLME request + * @param[out] mlme_confirm the MLME confirm. `mlme_confirm->status` could either + * be GNRC_LORAWAN_REQ_STATUS_SUCCESS if the request was OK, + * GNRC_LORAWAN_REQ_STATUS_DEFERRED if the confirmation is deferred + * or an standard error number + */ +void gnrc_lorawan_mlme_request(gnrc_lorawan_t *mac, const mlme_request_t *mlme_request, + mlme_confirm_t *mlme_confirm); + +/** + * @brief Perform a MCPS request + * + * @param[in] mac pointer to the MAC descriptor + * @param[in] mcps_request the MCPS request + * @param[out] mcps_confirm the MCPS confirm. `mlme_confirm->status` could either + * be GNRC_LORAWAN_REQ_STATUS_SUCCESS if the request was OK, + * GNRC_LORAWAN_REQ_STATUS_DEFERRED if the confirmation is deferred + * or an standard error number + */ +void gnrc_lorawan_mcps_request(gnrc_lorawan_t *mac, const mcps_request_t *mcps_request, + mcps_confirm_t *mcps_confirm); + +/** + * @brief Fetch a LoRaWAN packet from the radio. + * + * To be called on radio RX done event. + * + * @param[in] mac pointer to the MAC descriptor + */ +void gnrc_lorawan_recv(gnrc_lorawan_t *mac); + +/** + * @brief Setup GNRC LoRaWAN netdev layers + * + * @param mac pointer to the MAC descriptor + * @param lower pointer to the lower netdev device (radio) + */ +void gnrc_lorawan_setup(gnrc_lorawan_t *mac, netdev_t *lower); + +#ifdef __cplusplus +} +#endif + +#endif /* NET_GNRC_LORAWAN_H */ +/** @} */ diff --git a/sys/include/net/gnrc/lorawan/region.h b/sys/include/net/gnrc/lorawan/region.h new file mode 100644 index 0000000000..8ed2794550 --- /dev/null +++ b/sys/include/net/gnrc/lorawan/region.h @@ -0,0 +1,72 @@ +/* + * 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. + */ + +/** + * @ingroup net_gnrc_lorawan + * @{ + * + * @file + * @brief GNRC LoRaWAN region specific functions + * + * @author José Ignacio Alamos + */ +#ifndef NET_GNRC_LORAWAN_REGION_H +#define NET_GNRC_LORAWAN_REGION_H + +#include "kernel_defines.h" +#include "net/gnrc/lorawan.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Default LoRaWAN channels for current region (EU868) + */ +static const uint32_t gnrc_lorawan_default_channels[] = { + 868100000UL, + 868300000UL, + 868500000UL +}; + +#define GNRC_LORAWAN_DEFAULT_CHANNELS_NUMOF \ + ARRAY_SIZE(gnrc_lorawan_default_channels) /**< Number of default channels */ + +/** + * @brief Process Channel Frequency list frame + * + * @param[in] mac pointer to the MAC descriptor + * @param[in] cflist the CFList to be processed + */ +void gnrc_lorawan_process_cflist(gnrc_lorawan_t *mac, uint8_t *cflist); + +/** + * @brief Get the datarate of the first reception windows + * + * @param[in] dr_up the datarate of the transmission + * @param[in] dr_offset the offset of the first reception window + * + * @return datarate + */ +uint8_t gnrc_lorawan_rx1_get_dr_offset(uint8_t dr_up, uint8_t dr_offset); + +/** + * @brief Check if a datarate is valid in the current region + * + * @param[in] dr the datarate to be checked + * + * @return true if datarate is valid + * @return false otherwise + */ +bool gnrc_lorawan_validate_dr(uint8_t dr); + +#ifdef __cplusplus +} +#endif + +#endif /* NET_GNRC_LORAWAN_REGION_H */