fota lib for mdot
mdot/Lora/Mac.h
- Committer:
- rklaassen
- Date:
- 2019-01-15
- Revision:
- 8:7ba1f2abb8c0
- Parent:
- 3:63d10f2375ea
File content as of revision 8:7ba1f2abb8c0:
/** __ ___ ____ _ ______ __ ____ __ ____ * / |/ /_ __/ / /_(_)__/_ __/__ ____/ / / __/_ _____ / /____ __ _ ___ / _/__ ____ * / /|_/ / // / / __/ /___// / / -_) __/ _ \ _\ \/ // (_-</ __/ -_) ' \(_-< _/ // _ \/ __/ __ * /_/ /_/\_,_/_/\__/_/ /_/ \__/\__/_//_/ /___/\_, /___/\__/\__/_/_/_/___/ /___/_//_/\__/ /_/ * Copyright (C) 2015 by Multi-Tech Systems /___/ * * * @author Jason Reiss * @date 10-31-2015 * @brief lora::Mac implements the Mac layer providing mote addressing and packet encryption * * @details * */ #ifndef __LORA_MAC_H__ #define __LORA_MAC_H__ #include "Lora.h" #include "ChannelPlan.h" #include "SxRadio.h" #include "SxRadio1272.h" #include "SxRadioEvents.h" #include "MacEvents.h" #include "Crypto.h" #include "Link.h" namespace lora { class Mac: public SxRadioEvents, public Crypto { public: virtual ~Mac(); Mac(SxRadio& radio, MacEvents* events, ChannelPlan* plan, Settings& settings); /** * Send a Join Request packet * @param devEUI * @param appEUI * @param appKey * @return LORA_OK if successful * @return LORA_LINK_BUSY * @return LORA_RADIO_BUSY */ uint8_t Join(const uint8_t* devEUI, const uint8_t* appEUI, const uint8_t* appKey); /** * Send a packet * @param port app port to send with payload * @param payload data to send * @param size of payload * @param attempts number of attempts to receive an ACK * @param repeats number of times to repeat packet * @return LORA_OK if successful * @return LORA_MAX_PAYLOAD_EXCEEDED if payload size exceeds datarate maximum * @return LORA_NO_CHANS_ENABLED if there is not an available channel that supports the current datarate * @return LORA_LINK_BUSY if link was busy * @return LORA_RADIO_BUSY if radio was busy * @return LORA_BUFFER_FULL if mac commands filled the packet, client should resend the packet */ uint8_t Send(uint8_t port, const uint8_t* payload, uint16_t size, uint8_t attempts = 0, uint8_t repeats = 0); /** * Prepare frame to be sent over link * @param port to send data to * @param payload to send * @param size of payload * @param attempts 0:Unconfirmed, 1-8:Confirmed * @return LORA_OK */ uint8_t PrepareFrame(uint8_t port, const uint8_t* payload, uint8_t size, uint8_t attempts); /** * Reset the mac commands buffer */ void ResetMacCommands(); /** * Add a mac command to be sent with next packet * @param cmd id of command * @param pc number of parameters * @param pv array of parameters * @return LORA_OK if successful * @return LORA_COMMAND_BUFFER_FULL * @return LORA_UNKNOWN_MAC_COMMAND */ uint8_t AddMacCommand(uint8_t cmd, uint8_t pc, uint8_t* pv); /** * Handle mac command received from server * @param payload received on radio * @param index of mac command id * @param size of mac command list */ uint8_t HandleMacCommands(uint8_t* payload, uint8_t index, uint8_t size); /** * Handle Join Accept packet * @param payload received * @param size of payload * @return LORA_OK if successful * @return LORA_JOIN_ERROR if already joined or MIC fails */ uint8_t HandleJoinAccept(uint8_t* payload, uint8_t size); /** * Handle Packet receipt * Verifies Address and MIC, checks the Frame Control bits for ACK * Then decrypts the payload and handles any Mac Commands * @param payload received * @param size of payload * @param[out] port data was received on * @param[out] length of user data in payload */ uint8_t HandleDownlinkPacket(uint8_t* payload, uint8_t size, uint8_t& port, uint8_t& length); /** * Check for ACK from server in received packet and notifies Link if present * @param fCtrl frame control byte of packet * @return LORA_OK */ uint8_t CheckFrameControl(DownlinkControl fCtrl); /** * Verify that packet address is intended for mote or in list of multicast addresses * @param payload received * @param size of payload * @param[out] address found in header of packet * @param[out] networkSessionKey associated with address * @param[out] dataSessionKey associated with address * @return LORA_OK if successful * @return LORA_ADDRESS_ERROR if address is not found */ uint8_t VerifyAddress(uint8_t* payload, uint8_t size, uint32_t& address, uint8_t* networkSessionKey, uint8_t* dataSessionKey); /** * Verify that MIC can be computed with network session key * Frame counter is checked for reset and rollover * @param payload received * @param size of payload * @param address found in header of packet * @param networkSessionKey * @return LORA_OK if successful * @return LORA_MIC_ERROR */ uint8_t VerifyMIC(uint8_t* payload, uint8_t size, uint32_t address, uint8_t* networkSessionKey); /** * Event called by Link on start of any tx */ virtual void TxStart(void); /** * Event called by Link on tx done */ virtual void TxDone(void); /** * Event called by Link on tx timeout */ virtual void TxTimeout(void); /** * Event called by Link on rx done * @param payload of received packet * @param size of received packet in bytes * @param rssi of received packet in dBm * @param snr of received packet two's complement in 1/4 dB */ virtual void RxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr); /** * Event called by Link on rx timeout */ virtual void RxTimeout(void); /** * Event called by Link on rx error */ virtual void RxError(void); virtual void LinkIdle(void); /** * Current join status * @return true if joined to lora network * @return false if not joined */ bool IsJoined(); /** * Set the dev nonce * The dev nonce is used for deriving session keys and part of the data send on a join request */ void SetDeviceNonce(uint16_t nonce); /** * Get the dev nonce * The dev nonce is used for deriving session keys and part of the data send on a join request */ uint16_t GetDeviceNonce(); void SetLoraClass(MoteClass cls); /** * Get the current device MoteClass */ MoteClass GetLoraClass(); /** * Get the SNR of the last received packet * @returns snr in dB */ int8_t GetSNR(); /** * Get the RSSI of the last received packet * @returns rssi in dB */ int16_t GetRSSI(); /** * Update the statistics with the last received RSSI and SNR * The avg, min and max RSSI and SNR will also be updated */ void UpdateStats(int16_t rssi, int16_t snr); /** * Get the number of mac command bytes ready to be sent in the next packet * @return size of buffer in bytes */ uint8_t GetMacCommandBufferSize(); /** * Get the buffer for mac command bytes ready to be sent in the next packet * @return pointer to command buffer */ const uint8_t* GetMacCommandBuffer(); /** * Clear the buffer for mac command bytes to be sent in the next packet */ void ClearMacCommandBuffer(); /** * Get the size of the bytes ready to be sent in the next packet * @returns size of buffer in bytes */ uint8_t GetTxBufferSize(); /** * Get the buffer of bytes ready to be sent in the next packet * @return pointer to buffer */ const uint8_t* GetTxBuffer(); /** * Get the max duty cycle currently set for device * Aggregated duty cycle = 1 / 2 ^ MaxDutyCycle * Value of 255 should silence device * @return duty cycle 0-15 or 255 */ uint8_t GetMaxDutyCycle(); /** * Get the Rx delay value currently used by the Link * @return rxDelay in seconds */ uint8_t GetRxDelay(); /** * Get the MCU sleep time between tx done and the Rx1 window opening * @return Time MCU sleeps between tx done and rx1 open in milliseconds */ uint32_t GetRx1SleepTime(); /** * Get the MCU sleep time between Rx1 window opening and the Rx2 window opening * @return Time MCU sleeps between rx1 open and rx2 open in milliseconds */ uint32_t GetRx2SleepTime(); /** * Get pong received indicator * @return true if pong was received */ bool GetPongReceived(); /** * Get the RSSI of the last received pong * The RSSI will be the strength of the signal received at the gateway * @return rssi in dB */ int16_t GetPongRssi(); /** * Get the SNR of the last received pong * The SNR will be the strength of the signal received at the gateway * @return snr in dB */ int16_t GetPongSnr(); /** * Get the current statistics for the device * @return Statistics */ Statistics& GetStats(); /** * Reset the current statistics for the device */ void ResetStats(); /** * Set the current channel plan */ void SetChannelPlan(ChannelPlan* plan); /** * Set the delay for Rx1 window * @param sec time to delay after end of tx, minimum 1 second */ uint8_t SetRxDelay(uint8_t sec); /** * Set the MCU sleep time between tx done and the Rx1 window opening * @param ms time MCU sleeps between tx done and rx1 open */ void SetRx1SleepTime(uint32_t ms); /** * Set the MCU sleep time between Rx1 window opening and the Rx2 window opening * @param ms time MCU sleeps between rx1 open and rx2 open */ void SetRx2SleepTime(uint32_t ms); /** * Set the network mode * @param mode PRIVATE, PUBLIC or PEER_TO_PEER */ uint8_t SetNetworkMode(uint8_t mode); /** * Get the current state of the MAC layer * @return MAC_IDLE, MAC_TX, MAC_RX */ MacState GetState(); /** * Get the time off air for the current datarate * @return time off air before next TX in ms */ uint32_t GetTimeOffAir(); /** * Open an RX Window * @param timeout time in ms to hold window open, 0 for continuous * @param freq frequency to listen on * @param datarate to listen for * @return LORA_OK */ uint8_t OpenRxWindow(uint32_t timeout, uint32_t freq, uint8_t datarate); uint8_t OpenRxWindow(uint32_t timeout, bool continuous); /** * Close the open window * @return LORA_OK */ uint8_t CloseRxWindow(); /** * Cancel pending rx windows * @return LORA_OK */ uint8_t CancelRxWindows(); /** * Get datarate properties of given index for current channel plan * @param index of datarate */ Datarate GetDatarate(uint8_t index); /** * Get the max payload size available of current datarate for channel plan * @return bytes that can be sent */ uint8_t GetMaxPayloadSize(); /** * Call to wakeup mac layer */ void Wakeup(); /** * Set the event object to report to * @param events object inheriting from MacEvents */ void SetEventHandler(MacEvents* events); /** * Get the channels in use by current channel plan * @return channel frequencies */ std::vector<uint32_t> GetChannels(); /** * Get the downlink channels in use by current channel plan * @return channel frequencies */ std::vector<uint32_t> GetDownlinkChannels(); /** * Get the channel datarate ranges in use by current channel plan * @return channel datarate ranges */ std::vector<uint8_t> GetChannelRanges(); /** * Enable the default channels of the channel plan */ void EnableDefaultChannels(); /** * Get the number of duty bands in the current channel plan * @return number of bands */ uint8_t GetNumDutyBands(); /** * Get the time off air for the given duty band * @param band index * @return time off air in ms */ uint32_t GetDutyBandTimeOff(uint8_t band); /** * Set the time off air for the given duty band * @param band index * @param time off air in ms */ void SetDutyBandTimeOff(uint8_t band, uint32_t timeoff); /** * Reset internal mac state if timeout or unforeseen error occurs */ void ResetState(); /** * Enable TX CW * return LORA_OK */ uint8_t SendContinuous(bool enable); private: /** * Helper for clearing MAC commands which can be cleared upon successful uplink */ void PostTxMacPrune(); Link _link; //!< Link used to manage radio ChannelPlan* _plan; //!< Injected ChannelPlan used by Link to define parameters for tx/rx of packets SxRadio& _radio; //!< Injected SxRadio object MacEvents* _events; //!< Injected MaxEvents object for event notification to client Settings& _settings; //!< Settings used to configure the Mac bool _isMulticastPacket; //!< Indicator of multicast packet recieved uint8_t _multicastIndex; //!< Index of multicast session associated with last received packet uint8_t _rxBuffer[MAX_PHY_PACKET_SIZE]; //!< Buffer of last packet received uint8_t _rxBufferSize; //!< Size of the last packet received uint8_t _txBuffer[MAX_PHY_PACKET_SIZE]; //!< Buffer of packet to send uint8_t _txBufferSize; //!< Size of buffer to send bool _txBufferFull; //!< Indicates that buffer was filled with mac commands uint16_t _joinNonce; //!< Random nonce value used for Join Request and to derive session keys int16_t _rssi; //!< RSSI value of last received packet in dB int16_t _snr; //!< SNR value of last received packet in cB bool _pongReceived; //!< Indicator of pong received int16_t _pongRssi; //!< RSSI value of last received pong int16_t _pongSnr; //!< SNR value of last received pong MacState _state; //!< Current mac state uint32_t _downlinkCounter; //!< Temporary downlink counter bool _duplicateReceived; //!< Indication of duplicate packet received due to missed ack DownlinkControl _downlinkCtrl; //!< Downlink ctrl status of last rx packet }; } #endif // __LORA_MAC_H__