fota lib for mdot
mdot/Lora/Link.h
- Committer:
- Jenkins@KEILDM1.dc.multitech.prv
- Date:
- 2018-09-14
- Revision:
- 3:63d10f2375ea
File content as of revision 3:63d10f2375ea:
/** __ ___ ____ _ ______ __ ____ __ ____ * / |/ /_ __/ / /_(_)__/_ __/__ ____/ / / __/_ _____ / /____ __ _ ___ / _/__ ____ * / /|_/ / // / / __/ /___// / / -_) __/ _ \ _\ \/ // (_-</ __/ -_) ' \(_-< _/ // _ \/ __/ __ * /_/ /_/\_,_/_/\__/_/ /_/ \__/\__/_//_/ /___/\_, /___/\__/\__/_/_/_/___/ /___/_//_/\__/ /_/ * Copyright (C) 2015 by Multi-Tech Systems /___/ * * * @author Jason Reiss * @date 10-31-2015 * @brief lora::Link implements uses a channel plan to send and receive through an SX radio driver * * @details * @copyright Copyright (C) 2015 by Multi-Tech Systems. All rights reserved. This project is released under the GNU Lesser General Public License <http://www.gnu.org/licenses/>. * */ #ifndef __LORA_LINK_H__ #define __LORA_LINK_H__ #include "Lora.h" #include "SxRadio.h" #include "ChannelPlan.h" namespace lora { class Link: public SxRadioEvents { public: /** * Create a link object * @param events SxRadioEvents object to pass events to * @param radio SxRadio object for send and receive operations * @param plan ChannelPlan to define Frequencies and Datarates used in send and receive */ Link(SxRadioEvents& events, SxRadio& radio, ChannelPlan* plan); /** * Link destructor */ virtual ~Link(); /** * Get current state of link * @returns current state */ LinkState State(); // Event functions called by SxRadio class /** Event called by SxRadio on end of tx */ virtual void TxDone(void); /** Event called by SxRadio on tx timeout */ virtual void TxTimeout(void); /** Event called by SxRadio on end of rx */ virtual void RxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr); /** Event called by SxRadio on rx timeout */ virtual void RxTimeout(void); /** Event called by SxRadio on rx error */ virtual void RxError(void); /** Event called by Mac when bad packet recv */ virtual void RxNotValid(void); /** Event called by SxRadio on frequency hop request */ virtual void FhssChangeChannel(uint8_t currentChannel); // Link interface functions /** * Send the data in buffer with provided number of attempts or repeats * Radio is set according to current ChannelPlan * @param buffer data to send on radio * @param size number of bytes in buffer to send * @param attempts number of attempts receive an ack of CONFIRMED_FRAME * @param repeats number of times to repeat the packet, only used if attempts == 0 * @return LORA_OK if successful * @return LORA_NO_CHANS_ENABLED if there is not an available channel that supports the current datarate * @return LORA_LINK_BUSY or LORA_RADIO_BUSY if not successful */ virtual uint8_t Send(const uint8_t* buffer, uint16_t size, uint8_t attempts = 0, uint8_t repeats = 0); /** * Open receive window with provided timeout * Radio is set according to current ChannelPlan * @param window * @param timeout * @return LORA_OK if window is opened * @return LORA_RADIO_BUSY if window cannot be opened */ virtual uint8_t Recv(uint8_t window, uint32_t timeout, uint32_t freq = 0, bool force_continuous=false); /** * Set the delay between end of tx and start of first rx window * Second rx window will be opened 1 second after first * @param delay number of milliseconds */ virtual void SetRxDelayMs(uint32_t delay); /** * Get the delay between end of tx and start of first rx window * Second rx window will be opened 1 second after first * @return number of milliseconds */ virtual uint32_t GetRxDelayMs(); /** * Receive setting from Rx Timing Setup mac command * @param payload buffer containing mac command * @param index of mac command id in buffer * @param size of mac command id and params */ virtual uint8_t HandleRxTimingSetup(const uint8_t* payload, uint8_t index, uint8_t size); /** * Set the time the MCU is sleeping between tx done and rx1 window open * This is needed to compensate timers which don't run during a stop sleep mode * @param time in milliseconds of the sleep */ virtual void SetRx1SleepTime(uint32_t time); /** * Get the time the MCU is sleeping between tx done and rx1 window open * @return time in milliseconds of the sleep */ uint32_t GetRx1SleepTime(); /** * Set the time the MCU is sleeping between rx1 window open and rx2 window open * This is needed to compensate timers which don't run during a stop sleep mode * @param time in milliseconds of the sleep */ virtual void SetRx2SleepTime(uint32_t time); /** * Get the time the MCU is sleeping between rx1 window open and rx2 window open * @return time in milliseconds of the sleep */ uint32_t GetRx2SleepTime(); // Timer callback functions and events /** * Timer handler for first receive window */ static void OnRx1WindowTimer(void const *arg); /** * Event handler to open first receive window */ virtual void OnRx1WindowEvent(); /** * Timer handler for second receive window */ static void OnRx2WindowTimer(void const *arg); /** * Event handler to open second receive window */ void OnRx2WindowEvent(); /** * Timer handlers for receive window */ static void OnRxWindowTimer(void const *arg); /** * Event handler to close receive window on timeout */ virtual void OnRxWindowEvent(); /** * Callback for mac layer to notify link when ack has been received */ virtual void ReceivedAck(); /** * Flag indicating if ack was received with last rx packet * @return true if ack was received */ bool AckReceived(); /** * Open a receive window with provided timeout * @param timeout number of milliseconds before window will timeout, 0 == continuous * @return LORA_OK if window is opened * @return LORA_RADIO_BUSY if window cannot be opened */ virtual uint8_t OpenRxWindow(uint16_t timeout = 0, bool force_continuous=false); /** * Open a receive window with provided timeout, frequency and datarate * @param timeout number of milliseconds before window will timeout, 0 == continuous * @param frequecy to listen for * @param datarate to listen for * @return LORA_OK if window is opened * @return LORA_RADIO_BUSY if window cannot be opened */ virtual uint8_t OpenRxWindow(uint32_t timeout, uint32_t freq, uint8_t datarate); /** * Close the receive window */ void CloseRxWindow(); /** * Stop Rx2 Window Timer */ void StopRx2WindowTimer(); /** * Cancel pending rx windows */ void CancelRxWindows(); /** * Get link stats for number of up/down packets and missed acks * @return Statistics struct */ Statistics& GetStats(); /** * Set the current channel plan */ void SetChannelPlan(ChannelPlan* plan); /** Set the LoRaWAN class operation * @param cls A, B or C */ void SetLoraClass(lora::MoteClass cls); /** * Reset the internal state of the Link */ void ResetState(); /** * Ack retries attempted during last transmission request * @return number of ack retries attempted */ uint8_t TxRetries(); /** * Reset link statistics */ void ResetStats(); /** * Get the rx window we received the last packet in * @return rx window the last packet was received in */ uint8_t GetLastRxWindowUsed(); private: /** * Send data in tx buffer with current settings * Used for resending data on missed ack or repeating packets */ uint8_t Send(); /** * Injected SxRadioEvent object */ SxRadioEvents& _events; /** * Injected SxRadio object */ SxRadio& _radio; /** * Injected ChannelPlan object used to send and receive packets */ ChannelPlan* _plan; LinkState _state; //!< Current state of Link // Timers RtosTimer _rx1WindowTimer; //!< Timer to open first rx window RtosTimer _rx2WindowTimer; //!< Timer to open second rx window RtosTimer _rxWindowTimer; //!< Timer to close rx window RtosTimer _ackTimer; //!< Timer to send next attempt for confirmed frame RtosTimer _repeatTimer; //!< Timer to send next attempt for confirmed frame Timer _fakeRx2Timer; //!< Timer to fake rx2 window for class C bool _ackTimerPending; //!< Flag for resend bool _repeatTimerPending; //!< Flag for resend // Member variables uint8_t _txBuffer[MAX_PHY_PACKET_SIZE]; //!< Buffer for tx packets uint8_t _txBufferSize; //!< Size of buffer for tx packets uint32_t _rxDelayMs; //!< Current delay between end of tx and opening of first rx window uint32_t _rx1SleepTime; //!< MCU sleep time before rx1 opens (in ms) uint32_t _rx2SleepTime; //!< MCU sleep time before rx2 opens relative to rx1 open (in ms) uint8_t _ackAttemptsMax; //!< Number of attempts to transmit a confirmed packet uint8_t _ackAttempts; //!< Attempt number of current packet uint8_t _repeatsMax; //!< Number of times to repeat a packet uint8_t _repeats; //!< Repeat number of current packet bool _ackReceived; Statistics _stats; //!< Statistics for Up/Down packets and missed ACK's MoteClass _loraClass; uint8_t _lastRxWndOpened; //!< Last rx window opened uint8_t _lastRxWnd; //!< Rx window last packet was received in /** * Callback for radio thread to signal */ virtual void MacEvent(); /** * Timer handler for ACK timeout */ static void OnAckTimeout(void const *arg); /** * Event handler for ACK timeout */ void OnAckTimeoutEvent(); /** * Timer handler for ACK timeout */ static void OnRepeatTimeout(void const *arg); /** * Event handler for ACK timeout */ void OnRepeatTimeoutEvent(); /** * Update link state */ void UpdateState(); }; } #endif