/** * \file LoRaMacCommand.h * * \brief LoRa MAC layer implementation * * \copyright Revised BSD License, see LICENSE.TXT file include in the project * * \code * ______ _ * / _____) _ | | * ( (____ _____ ____ _| |_ _____ ____| |__ * \____ \| ___ | (_ _) ___ |/ ___) _ \ * _____) ) ____| | | || |_| ____( (___| | | | * (______/|_____)_|_|_| \__)_____)\____)_| |_| * (C)2013 Semtech * * ___ _____ _ ___ _ _____ ___ ___ ___ ___ * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| * embedded.connectivity.solutions=============== * * \endcode * * \author Miguel Luis ( Semtech ) * * \author Gregory Cristian ( Semtech ) * * \author Daniel Jaeckle ( STACKFORCE ) * * \defgroup LORAMAC LoRa MAC layer implementation * This module specifies the API implementation of the LoRaMAC layer. * This is a placeholder for a detailed description of the LoRaMac * layer and the supported features. * * Copyright (c) 2017, Arm Limited and affiliates. * SPDX-License-Identifier: BSD-3-Clause * */ #ifndef __LORAMACCOMMAND_H__ #define __LORAMACCOMMAND_H__ #include <stdint.h> #include "system/lorawan_data_structures.h" #include "lorastack/phy/LoRaPHY.h" /*! * Maximum MAC commands buffer size */ #define LORA_MAC_COMMAND_MAX_LENGTH 128 class LoRaMac; /** LoRaMacCommand Class * Helper class for LoRaMac layer to handle any MAC commands */ class LoRaMacCommand { public: LoRaMacCommand(); /** * @brief Clear MAC command buffer. */ void clear_command_buffer(void); /** * @brief Get the length of MAC commands * * @return status Length of used MAC buffer (bytes) */ uint8_t get_mac_cmd_length() const; /** * @brief Get MAC command buffer * * @return Pointer to MAC command buffer */ uint8_t *get_mac_commands_buffer(); /** * @brief Parses the MAC commands which must be re-sent. */ void parse_mac_commands_to_repeat(); /** * @brief Clear MAC command repeat buffer. */ void clear_repeat_buffer(); /** * @brief Copy MAC commands from repeat buffer to actual MAC command buffer. */ void copy_repeat_commands_to_buffer(); /** * @brief Get the length of MAC commands in repeat buffer * * @return status Length of used MAC Repeat buffer (bytes) */ uint8_t get_repeat_commands_length() const; /** * @brief Clear sticky MAC commands. */ void clear_sticky_mac_cmd(); /** * @brief Check if MAC command buffer contains sticky commands * * @return status True: buffer has sticky MAC commands in it, false: no sticky commands in buffer */ bool has_sticky_mac_cmd() const; /** * @brief Decodes MAC commands in the fOpts field and in the payload * * @return status Function status. LORAWAN_STATUS_OK if command successful. */ lorawan_status_t process_mac_commands(const uint8_t *payload, uint8_t mac_index, uint8_t commands_size, uint8_t snr, loramac_mlme_confirm_t &mlme_conf, lora_mac_system_params_t &mac_params, LoRaPHY &lora_phy); /** * @brief Adds a new LinkCheckReq MAC command to be sent. * * @return status Function status: LORAWAN_STATUS_OK: OK, * LORAWAN_STATUS_LENGTH_ERROR: Buffer full */ lorawan_status_t add_link_check_req(); /** * @brief Set battery level query callback method * If callback is not set, BAT_LEVEL_NO_MEASURE is returned. */ void set_batterylevel_callback(mbed::Callback<uint8_t(void)> battery_level); private: /** * @brief Get the remaining size of the MAC command buffer * * @return Remaining free space in buffer (bytes). */ int32_t cmd_buffer_remaining() const; /** * @brief Adds a new LinkAdrAns MAC command to be sent. * * @param [in] status Status bits * * @return status Function status: LORAWAN_STATUS_OK: OK, * LORAWAN_STATUS_LENGTH_ERROR: Buffer full */ lorawan_status_t add_link_adr_ans(uint8_t status); /** * @brief Adds a new DutyCycleAns MAC command to be sent. * * @return status Function status: LORAWAN_STATUS_OK: OK, * LORAWAN_STATUS_LENGTH_ERROR: Buffer full */ lorawan_status_t add_duty_cycle_ans(); /** * @brief Adds a new RXParamSetupAns MAC command to be sent. * * @param [in] status Status bits * * @return status Function status: LORAWAN_STATUS_OK: OK, * LORAWAN_STATUS_LENGTH_ERROR: Buffer full */ lorawan_status_t add_rx_param_setup_ans(uint8_t status); /** * @brief Adds a new DevStatusAns MAC command to be sent. * * @param [in] battery Battery level * @param [in] margin Demodulation signal-to-noise ratio (dB) * * @return status Function status: LORAWAN_STATUS_OK: OK, * LORAWAN_STATUS_LENGTH_ERROR: Buffer full */ lorawan_status_t add_dev_status_ans(uint8_t battery, uint8_t margin); /** * @brief Adds a new NewChannelAns MAC command to be sent. * * @param [in] status Status bits * * @return status Function status: LORAWAN_STATUS_OK: OK, * LORAWAN_STATUS_LENGTH_ERROR: Buffer full */ lorawan_status_t add_new_channel_ans(uint8_t status); /** * @brief Adds a new RXTimingSetupAns MAC command to be sent. * * @return status Function status: LORAWAN_STATUS_OK: OK, * LORAWAN_STATUS_LENGTH_ERROR: Buffer full */ lorawan_status_t add_rx_timing_setup_ans(); /** * @brief Adds a new TXParamSetupAns MAC command to be sent. * * @return status Function status: LORAWAN_STATUS_OK: OK, * LORAWAN_STATUS_LENGTH_ERROR: Buffer full */ lorawan_status_t add_tx_param_setup_ans(); /** * @brief Adds a new DlChannelAns MAC command to be sent. * * @param [in] status Status bits * * @return status Function status: LORAWAN_STATUS_OK: OK, * LORAWAN_STATUS_LENGTH_ERROR: Buffer full */ lorawan_status_t add_dl_channel_ans(uint8_t status); private: /** * Indicates if there are any pending sticky MAC commands */ bool sticky_mac_cmd; /** * Contains the current Mac command buffer index in 'mac_cmd_buffer' */ uint8_t mac_cmd_buf_idx; /** * Contains the current Mac command buffer index for MAC commands to repeat in * 'mac_cmd_buffer_to_repeat' */ uint8_t mac_cmd_buf_idx_to_repeat; /** * Buffer containing the MAC layer commands */ uint8_t mac_cmd_buffer[LORA_MAC_COMMAND_MAX_LENGTH]; /** * Buffer containing the MAC layer commands which must be repeated */ uint8_t mac_cmd_buffer_to_repeat[LORA_MAC_COMMAND_MAX_LENGTH]; mbed::Callback<uint8_t(void)> _battery_level_cb; }; #endif //__LORAMACCOMMAND_H__