fota lib for mdot

Dependents:   UQ_LoraWAN

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Link.h Source File

Link.h

00001 /**   __  ___     ____  _    ______        __     ____         __                  ____
00002  *   /  |/  /_ __/ / /_(_)__/_  __/__ ____/ /    / __/_ _____ / /____ __ _  ___   /  _/__  ____
00003  *  / /|_/ / // / / __/ /___// / / -_) __/ _ \  _\ \/ // (_-</ __/ -_)  ' \(_-<  _/ // _ \/ __/  __
00004  * /_/  /_/\_,_/_/\__/_/    /_/  \__/\__/_//_/ /___/\_, /___/\__/\__/_/_/_/___/ /___/_//_/\__/  /_/
00005  * Copyright (C) 2015 by Multi-Tech Systems        /___/
00006  *
00007  *
00008  * @author Jason Reiss
00009  * @date   10-31-2015
00010  * @brief  lora::Link implements uses a channel plan to send and receive through an SX radio driver
00011  *
00012  * @details
00013  * @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/>.
00014  *
00015  */
00016 
00017 #ifndef __LORA_LINK_H__
00018 #define __LORA_LINK_H__
00019 
00020 #include "Lora.h"
00021 #include "SxRadio.h"
00022 #include "ChannelPlan.h"
00023 
00024 namespace lora {
00025 
00026     class Link: public SxRadioEvents {
00027 
00028         public:
00029             /**
00030              * Create a link object
00031              * @param events SxRadioEvents object to pass events to
00032              * @param radio SxRadio object for send and receive operations
00033              * @param plan ChannelPlan to define Frequencies and Datarates used in send and receive
00034              */
00035             Link(SxRadioEvents& events, SxRadio& radio, ChannelPlan* plan);
00036 
00037             /**
00038              * Link destructor
00039              */
00040             virtual ~Link();
00041 
00042             /**
00043              * Get current state of link
00044              * @returns current state
00045              */
00046             LinkState State();
00047 
00048             // Event functions called by SxRadio class
00049 
00050             /** Event called by SxRadio on end of tx
00051              */
00052             virtual void TxDone(void);
00053 
00054             /** Event called by SxRadio on tx timeout
00055              */
00056             virtual void TxTimeout(void);
00057 
00058             /** Event called by SxRadio on end of rx
00059              */
00060             virtual void RxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr);
00061 
00062             /** Event called by SxRadio on rx timeout
00063              */
00064             virtual void RxTimeout(void);
00065 
00066             /** Event called by SxRadio on rx error
00067              */
00068             virtual void RxError(void);
00069 
00070             /** Event called by Mac when bad packet recv
00071              */
00072             virtual void RxNotValid(void);
00073 
00074             /** Event called by SxRadio on frequency hop request
00075              */
00076             virtual void FhssChangeChannel(uint8_t currentChannel);
00077 
00078             // Link interface functions
00079 
00080             /**
00081              * Send the data in buffer with provided number of attempts or repeats
00082              * Radio is set according to current ChannelPlan
00083              * @param buffer data to send on radio
00084              * @param size number of bytes in buffer to send
00085              * @param attempts number of attempts receive an ack of CONFIRMED_FRAME
00086              * @param repeats number of times to repeat the packet, only used if attempts == 0
00087              * @return LORA_OK if successful
00088              * @return LORA_NO_CHANS_ENABLED if there is not an available channel that supports the current datarate
00089              * @return LORA_LINK_BUSY or LORA_RADIO_BUSY if not successful
00090              */
00091             virtual uint8_t Send(const uint8_t* buffer, uint16_t size, uint8_t attempts = 0, uint8_t repeats = 0);
00092 
00093             /**
00094              * Open receive window with provided timeout
00095              * Radio is set according to current ChannelPlan
00096              * @param window
00097              * @param timeout
00098              * @return LORA_OK if window is opened
00099              * @return LORA_RADIO_BUSY if window cannot be opened
00100              */
00101             virtual uint8_t Recv(uint8_t window, uint32_t timeout, uint32_t freq = 0, bool force_continuous=false);
00102 
00103             /**
00104              * Set the delay between end of tx and start of first rx window
00105              * Second rx window will be opened 1 second after first
00106              * @param delay number of milliseconds
00107              */
00108             virtual void SetRxDelayMs(uint32_t delay);
00109 
00110             /**
00111              * Get the delay between end of tx and start of first rx window
00112              * Second rx window will be opened 1 second after first
00113              * @return number of milliseconds
00114              */
00115             virtual uint32_t GetRxDelayMs();
00116 
00117             /**
00118              * Receive setting from Rx Timing Setup mac command
00119              * @param payload buffer containing mac command
00120              * @param index of mac command id in buffer
00121              * @param size of mac command id and params
00122              */
00123             virtual uint8_t HandleRxTimingSetup(const uint8_t* payload, uint8_t index, uint8_t size);
00124 
00125             /**
00126              * Set the time the MCU is sleeping between tx done and rx1 window open
00127              * This is needed to compensate timers which don't run during a stop sleep mode
00128              * @param time in milliseconds of the sleep
00129              */
00130             virtual void SetRx1SleepTime(uint32_t time);
00131 
00132             /**
00133              * Get the time the MCU is sleeping between tx done and rx1 window open
00134              * @return time in milliseconds of the sleep
00135              */
00136             uint32_t GetRx1SleepTime();
00137 
00138             /**
00139              * Set the time the MCU is sleeping between rx1 window open and rx2 window open
00140              * This is needed to compensate timers which don't run during a stop sleep mode
00141              * @param time in milliseconds of the sleep
00142              */
00143             virtual void SetRx2SleepTime(uint32_t time);
00144 
00145             /**
00146              * Get the time the MCU is sleeping between rx1 window open and rx2 window open
00147              * @return time in milliseconds of the sleep
00148              */
00149             uint32_t GetRx2SleepTime();
00150 
00151             // Timer callback functions and events
00152 
00153             /**
00154              * Timer handler for first receive window
00155              */
00156             static void OnRx1WindowTimer(void const *arg);
00157 
00158             /**
00159              * Event handler to open first receive window
00160              */
00161             virtual void OnRx1WindowEvent();
00162 
00163             /**
00164              * Timer handler for second receive window
00165              */
00166             static void OnRx2WindowTimer(void const *arg);
00167 
00168             /**
00169              * Event handler to open second receive window
00170              */
00171             void OnRx2WindowEvent();
00172 
00173             /**
00174              * Timer handlers for receive window
00175              */
00176             static void OnRxWindowTimer(void const *arg);
00177 
00178             /**
00179              * Event handler to close receive window on timeout
00180              */
00181             virtual void OnRxWindowEvent();
00182 
00183             /**
00184              * Callback for mac layer to notify link when ack has been received
00185              */
00186             virtual void ReceivedAck();
00187 
00188             /**
00189              * Flag indicating if ack was received with last rx packet
00190              * @return true if ack was received
00191              */
00192             bool AckReceived();
00193 
00194             /**
00195              * Open a receive window with provided timeout
00196              * @param timeout number of milliseconds before window will timeout, 0 == continuous
00197              * @return LORA_OK if window is opened
00198              * @return LORA_RADIO_BUSY if window cannot be opened
00199              */
00200             virtual uint8_t OpenRxWindow(uint16_t timeout = 0, bool force_continuous=false);
00201 
00202             /**
00203              * Open a receive window with provided timeout, frequency and datarate
00204              * @param timeout number of milliseconds before window will timeout, 0 == continuous
00205              * @param frequecy to listen for
00206              * @param datarate to listen for
00207              * @return LORA_OK if window is opened
00208              * @return LORA_RADIO_BUSY if window cannot be opened
00209              */
00210             virtual uint8_t OpenRxWindow(uint32_t timeout, uint32_t freq, uint8_t datarate);
00211 
00212             /**
00213              * Close the receive window
00214              */
00215             void CloseRxWindow();
00216 
00217             /**
00218          * Stop Rx2 Window Timer
00219          */
00220             void StopRx2WindowTimer();
00221 
00222             /**
00223              * Cancel pending rx windows
00224              */
00225             void CancelRxWindows();
00226 
00227             /**
00228              * Get link stats for number of up/down packets and missed acks
00229              * @return Statistics struct
00230              */
00231             Statistics& GetStats();
00232 
00233             /**
00234              * Set the current channel plan
00235              */
00236             void SetChannelPlan(ChannelPlan* plan);
00237 
00238             /** Set the LoRaWAN class operation
00239              * @param cls A, B or C
00240              */
00241             void SetLoraClass(lora::MoteClass cls);
00242 
00243             /**
00244              * Reset the internal state of the Link
00245              */
00246             void ResetState();
00247 
00248             /**
00249              * Ack retries attempted during last transmission request
00250              * @return number of ack retries attempted
00251              */
00252             uint8_t TxRetries();
00253 
00254             /**
00255              * Reset link statistics
00256              */
00257             void ResetStats();
00258 
00259             /**
00260              * Get the rx window we received the last packet in
00261              * @return rx window the last packet was received in
00262              */
00263             uint8_t GetLastRxWindowUsed();
00264 
00265         private:
00266 
00267             /**
00268              * Send data in tx buffer with current settings
00269              * Used for resending data on missed ack or repeating packets
00270              */
00271             uint8_t Send();
00272 
00273             /**
00274              * Injected SxRadioEvent object
00275              */
00276 
00277             SxRadioEvents& _events;
00278 
00279             /**
00280              * Injected SxRadio object
00281              */
00282             SxRadio& _radio;
00283 
00284             /**
00285              * Injected ChannelPlan object used to send and receive packets
00286              */
00287             ChannelPlan* _plan;
00288 
00289             LinkState _state;                       //!< Current state of Link
00290 
00291             // Timers
00292 
00293             RtosTimer _rx1WindowTimer;              //!< Timer to open first rx window
00294             RtosTimer _rx2WindowTimer;              //!< Timer to open second rx window
00295             RtosTimer _rxWindowTimer;               //!< Timer to close rx window
00296             RtosTimer _ackTimer;                    //!< Timer to send next attempt for confirmed frame
00297             RtosTimer _repeatTimer;                 //!< Timer to send next attempt for confirmed frame
00298             Timer     _fakeRx2Timer;                //!< Timer to fake rx2 window for class C
00299             bool _ackTimerPending;                  //!< Flag for resend
00300             bool _repeatTimerPending;               //!< Flag for resend
00301 
00302             // Member variables
00303             uint8_t _txBuffer[MAX_PHY_PACKET_SIZE]; //!< Buffer for tx packets
00304             uint8_t _txBufferSize;                  //!< Size of buffer for tx packets
00305 
00306             uint32_t _rxDelayMs;                    //!< Current delay between end of tx and opening of first rx window
00307             uint32_t _rx1SleepTime;                 //!< MCU sleep time before rx1 opens (in ms)
00308             uint32_t _rx2SleepTime;                 //!< MCU sleep time before rx2 opens relative to rx1 open (in ms)
00309 
00310             uint8_t _ackAttemptsMax;                //!< Number of attempts to transmit a confirmed packet
00311             uint8_t _ackAttempts;                   //!< Attempt number of current packet
00312             uint8_t _repeatsMax;                    //!< Number of times to repeat a packet
00313             uint8_t _repeats;                       //!< Repeat number of current packet
00314             bool _ackReceived;
00315 
00316             Statistics _stats;                      //!< Statistics for Up/Down packets and missed ACK's
00317 
00318             MoteClass _loraClass;
00319 
00320             uint8_t _lastRxWndOpened;               //!< Last rx window opened
00321             uint8_t _lastRxWnd;                     //!< Rx window last packet was received in
00322 
00323             /**
00324              *  Callback for radio thread to signal
00325              */
00326             virtual void MacEvent();
00327 
00328             /**
00329              * Timer handler for ACK timeout
00330              */
00331             static void OnAckTimeout(void const *arg);
00332 
00333             /**
00334              * Event handler for ACK timeout
00335              */
00336             void OnAckTimeoutEvent();
00337 
00338             /**
00339              * Timer handler for ACK timeout
00340              */
00341             static void OnRepeatTimeout(void const *arg);
00342 
00343             /**
00344              * Event handler for ACK timeout
00345              */
00346             void OnRepeatTimeoutEvent();
00347 
00348             /**
00349              * Update link state
00350              */
00351             void UpdateState();
00352     };
00353 
00354 }
00355 
00356 #endif