MultiTech / libxDot-dev-mbed5-deprecated

Dependents:   Dot-Examples Dot-AT-Firmware Dot-Examples TEST_FF1705 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ChannelPlan.h Source File

ChannelPlan.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::ChannelPlan provides an interface for LoRaWAN channel schemes
00011  *
00012  * @details
00013  *
00014  */
00015 
00016 #ifndef __CHANNEL_STRATEGY_H__
00017 #define __CHANNEL_STRATEGY_H__
00018 
00019 #include "mbed_events.h"
00020 
00021 #include "Lora.h"
00022 #include "SxRadio.h"
00023 #include <vector>
00024 
00025 namespace lora {
00026 
00027     class ChannelPlan {
00028         public:
00029 
00030             /**
00031              * Descriptions for channel plans & region information.
00032              * Bits 0-2 represent the plan type (fixed or dynamic)
00033              *   0b000              cannot be used as plans may line up with old definitions and cause much badness
00034              *   0b001              fixed channel plans
00035              *   0b010              dynamic channel plans
00036              *   0b011 - 0b111      RFU
00037              * Bits 3-7 represent the specific channel plan/region within the plan type
00038              */
00039             enum PlanType {
00040                 FIXED = 0x20,
00041                 DYNAMIC = 0x40,
00042             };
00043 
00044             enum Plan {
00045                 EU868_OLD = 0x00,
00046                 US915_OLD = 0x01,
00047                 AU915_OLD = 0x02,
00048 
00049                 FB_EU868 = 0x00,
00050                 FB_US915 = 0x01,
00051                 FB_AU915 = 0x02,
00052 
00053                 FB_868 = 0x00,
00054                 FB_915 = 0x01,
00055 
00056                 US915 = FIXED | 0x00,
00057                 AU915 = FIXED | 0x01,
00058 
00059                 EU868 = DYNAMIC | 0x00,
00060                 IN865 = DYNAMIC | 0x01,
00061                 AS923 = DYNAMIC | 0x02,
00062                 KR920 = DYNAMIC | 0x03,
00063                 AS923_JAPAN = DYNAMIC | 0x04,
00064                 RU864 = DYNAMIC | 0x05,
00065 
00066                 NONE = 0xFF,
00067             };
00068 
00069             /**
00070              * ChannelPlan constructor
00071              * @param radio SxRadio object used to set Tx/Rx config
00072              * @param settings Settings object
00073              */
00074             ChannelPlan(SxRadio* radio, Settings* settings);
00075 
00076             /**
00077              * ChannelPlan destructor
00078              */
00079             virtual ~ChannelPlan();
00080             
00081             /**
00082              * Checks that at least one channel exist for the data rate
00083              */
00084             virtual uint8_t ValidateAdrDatarate(uint8_t status);
00085 
00086             /**
00087              * Initialize channels, datarates and duty cycle bands according to current channel plan in settings
00088              */
00089             virtual void Init() = 0;
00090 
00091             /**
00092              * Set SxRadio object to be used to set Tx/Rx config
00093              */
00094             virtual void SetRadio(SxRadio* radio);
00095 
00096             /**
00097              * Set Settings object
00098              */
00099             virtual void SetSettings(Settings* settings);
00100 
00101             /**
00102              * Setter for the event queue
00103              */
00104             virtual void SetEventQueue(EventQueue* queue);
00105 
00106             /**
00107              * Get the next channel to use to transmit
00108              * @return LORA_OK if channel was found
00109              * @return LORA_NO_CHANS_ENABLED
00110              */
00111             virtual uint8_t GetNextChannel() = 0;
00112 
00113             /**
00114              * Set the number of channels in the plan
00115              */
00116             virtual void SetNumberOfChannels(uint8_t channels, bool resize = true);
00117 
00118             /**
00119              * Get the number of channels in the plan
00120              */
00121             virtual uint8_t GetNumberOfChannels();
00122 
00123             /**
00124              * Check if channel is enabled
00125              * @return true if enabled
00126              */
00127             virtual bool IsChannelEnabled(uint8_t channel);
00128 
00129             /**
00130              * Set a 16 bit channel mask with offset
00131              * @param index of mask to set 0:0-15, 1:16-31 ...
00132              * @param mask 16 bit mask of enabled channels
00133              * @return true
00134              */
00135             virtual bool SetChannelMask(uint8_t index, uint16_t mask);
00136 
00137             /**
00138              * Get the channel mask of currently enabled channels
00139              * @return vector containing channel bit masks
00140              */
00141             virtual std::vector<uint16_t> GetChannelMask();
00142 
00143             /**
00144              * Add a channel to the ChannelPlan
00145              * @param index of channel, use -1 to add to end
00146              * @param channel settings to add
00147              */
00148             virtual uint8_t AddChannel(int8_t index, Channel channel) = 0;
00149 
00150             /**
00151              * Get channel at index
00152              * @return Channel
00153              */
00154             virtual Channel GetChannel(int8_t index) = 0;
00155 
00156             /**
00157              * Add a downlink channel to the ChannelPlan
00158              * Set to 0 to use the default uplink channel frequency
00159              * @param index of channel, use -1 to add to end
00160              * @param channel settings to add
00161              */
00162             virtual uint8_t AddDownlinkChannel(int8_t index, Channel channel);
00163 
00164             /**
00165              * Get channel at index
00166              * @return Channel
00167              */
00168             virtual Channel GetDownlinkChannel(uint8_t index);
00169 
00170             /**
00171              * Set number of datarates in ChannelPlan
00172              * @param datarates
00173              */
00174             virtual void SetNumberOfDatarates(uint8_t datarates);
00175 
00176             /**
00177              * Add a datarate to the ChannelPlan
00178              * @param index of datarate, use -1 to add to end
00179              * @param datarate settings to add
00180              */
00181             virtual uint8_t AddDatarate(int8_t index, Datarate datarate);
00182 
00183             /**
00184              * Get datarate at index
00185              * @return Datarate
00186              */
00187             virtual Datarate GetDatarate(int8_t index);
00188 
00189             /**
00190              * Get max payload size for current datarate
00191              * @return size in bytes
00192              */
00193             virtual uint8_t GetMaxPayloadSize();
00194 
00195             /**
00196              * Get rx window settings for requested window
00197              * RX_1, RX_2, RX_BEACON, RX_SLOT
00198              * @param window
00199              * @return RxWindow
00200              */
00201             virtual RxWindow GetRxWindow(uint8_t window) = 0;
00202 
00203             /**
00204              * Get current channel to use for transmitting
00205              * @param channel index of channel
00206              * @return LORA_OK
00207              */
00208             virtual uint8_t SetTxChannel(uint8_t channel);
00209 
00210             /**
00211              * Get datarate to use on the join request
00212              * @return datarate index
00213              */
00214             virtual uint8_t GetJoinDatarate() = 0;
00215 
00216             /**
00217              * Calculate the next time a join request is possible
00218              * @param size of join frame
00219              * @returns LORA_OK
00220              */
00221             virtual uint8_t CalculateJoinBackoff(uint8_t size) = 0;
00222 
00223             /**
00224              * Get the current datarate
00225              * @return Datarate
00226              */
00227             virtual Datarate GetTxDatarate();
00228 
00229             /**
00230              * Set the current datarate
00231              * @param index of datarate
00232              * @return LORA_OK
00233              */
00234             virtual uint8_t SetTxDatarate(uint8_t index);
00235 
00236             /**
00237              * Set the datarate offset used for first receive window
00238              * @param offset
00239              * @return LORA_OK
00240              */
00241             virtual uint8_t SetRx1Offset(uint8_t offset);
00242 
00243             /**
00244              * Set the frequency for second receive window
00245              * @param freq
00246              * @return LORA_OK
00247              */
00248             virtual uint8_t SetRx2Frequency(uint32_t freq);
00249 
00250             /**
00251              * Set the datarate index used for second receive window
00252              * @param index
00253              * @return LORA_OK
00254              */
00255             virtual uint8_t SetRx2DatarateIndex(uint8_t index);
00256 
00257             /**
00258              * Get next channel and set the SxRadio tx config with current settings
00259              * @return LORA_OK
00260              */
00261             virtual uint8_t SetTxConfig() = 0;
00262 
00263             /**
00264              * Set the SxRadio rx config provided window
00265              * @param window to be opened
00266              * @param continuous keep window open
00267              * @param wnd_growth factor to increase the rx window by
00268              * @return LORA_OK
00269              */
00270             virtual uint8_t SetRxConfig(uint8_t window, bool continuous, uint16_t wnd_growth = 1) = 0;
00271 
00272             /**
00273              * Set frequency sub band if supported by plan
00274              * @param sub_band
00275              * @return LORA_OK
00276              */
00277             virtual uint8_t SetFrequencySubBand(uint8_t group) = 0;
00278 
00279             /**
00280              * Get frequency sub band if supported by plan
00281              * @return sub band 0-8 or 0 if not supported
00282              */
00283             virtual uint8_t GetFrequencySubBand();
00284 
00285             /**
00286              * Reset the ack counter used to lower datarate if ACK's are missed
00287              */
00288             virtual void ResetAckCounter();
00289 
00290             /**
00291              * Callback for radio to request channel change when frequency hopping
00292              * @param currentChannel
00293              */
00294             virtual void FhssChangeChannel(uint8_t currentChannel);
00295 
00296             /**
00297              * Callback for ACK timeout event
00298              * @return LORA_OK
00299              */
00300             virtual uint8_t HandleAckTimeout();
00301 
00302             /**
00303              * Callback for Join Accept packet to load optional channels
00304              * @return LORA_OK
00305              */
00306             virtual uint8_t HandleJoinAccept(const uint8_t* buffer, uint8_t size) = 0;
00307 
00308             /**
00309              * Callback to for rx parameter setup ServerCommand
00310              * @param payload packet data
00311              * @param index of start of command buffer
00312              * @param size number of bytes in command buffer
00313              * @param[out] status to be returned in MoteCommand answer
00314              * @return LORA_OK
00315              */
00316             virtual uint8_t HandleRxParamSetup(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) = 0;
00317 
00318             /**
00319              * Callback to for new channel ServerCommand
00320              * @param payload packet data
00321              * @param index of start of command buffer
00322              * @param size number of bytes in command buffer
00323              * @param[out] status to be returned in MoteCommand answer
00324              * @return LORA_OK
00325              */
00326             virtual uint8_t HandleNewChannel(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) = 0;
00327 
00328             /**
00329              * Callback to for downlink channel request ServerCommand
00330              * @param payload packet data
00331              * @param index of start of command buffer
00332              * @param size number of bytes in command buffer
00333              * @param[out] status to be returned in MoteCommand answer
00334              * @return LORA_OK
00335              */
00336             virtual uint8_t HandleDownlinkChannelReq(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status);
00337 
00338             /**
00339              * Callback to for ping slot channel request ServerCommand
00340              * @param payload packet data
00341              * @param index of start of command buffer
00342              * @param size number of bytes in command buffer
00343              * @param[out] status to be returned in MoteCommand answer
00344              * @return LORA_OK
00345              */
00346             virtual uint8_t HandlePingSlotChannelReq(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) = 0;
00347 
00348             /**
00349              * Callback to for beacon frequency request ServerCommand
00350              * @param payload packet data
00351              * @param index of start of command buffer
00352              * @param size number of bytes in command buffer
00353              * @param[out] status to be returned in MoteCommand answer
00354              * @return LORA_OK
00355              */
00356             virtual uint8_t HandleBeaconFrequencyReq(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) = 0;
00357 
00358             /**
00359              * Callback to for adaptive datarate ServerCommand
00360              * @param payload packet data
00361              * @param index of start of command buffer
00362              * @param size number of bytes in command buffer
00363              * @param[out] status to be returned in MoteCommand answer
00364              * @return LORA_OK
00365              */
00366             virtual uint8_t HandleAdrCommand(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) = 0;
00367 
00368             /**
00369              * Validate the configuration after multiple ADR commands have been applied
00370              * @return status to be returned in MoteCommand answer
00371              */
00372             virtual uint8_t ValidateAdrConfiguration() = 0;
00373 
00374             /**
00375              * Check that Rf Frequency is within channel plan range
00376              * @param freq frequency in Hz
00377              * @return true if valid frequency
00378              */
00379             virtual bool CheckRfFrequency(uint32_t freq);
00380 
00381             /**
00382              * Flag for ADR
00383              * @return true if ADR is enable in settings
00384              */
00385             virtual bool IsAdrEnabled();
00386 
00387             /**
00388              * Flag if ADR ACK should be sent in next packet
00389              * @return true when flag should be set
00390              */
00391             virtual bool AdrAckReq();
00392 
00393             /**
00394              * Increment the ADR counter to track when ADR ACK request should be sent
00395              * @return current value
00396              */
00397             virtual uint8_t IncAdrCounter();
00398 
00399             /**
00400              * Reset the ADR counter when valid downlink is received from network server
00401              */
00402             virtual void ResetAdrCounter();
00403 
00404             /**
00405              * Get the time the radio must be off air to comply with regulations
00406              * Time to wait may be dependent on duty-cycle restrictions per channel
00407              * Or duty-cycle of join requests if OTAA is being attempted
00408              * @return ms of time to wait for next tx opportunity
00409              */
00410             virtual uint32_t GetTimeOffAir() = 0;
00411 
00412             /**
00413              * Get the channels in use by current channel plan
00414              * @return channel frequencies
00415              */
00416             virtual std::vector<uint32_t> GetChannels() = 0;
00417 
00418             /**
00419              * Get the downlink channels in use by current channel plan
00420              * @return channel frequencies
00421              */
00422             virtual std::vector<uint32_t> GetDownlinkChannels();
00423 
00424             /**
00425              * Get the channel datarate ranges in use by current channel plan
00426              * @return channel datarate ranges
00427              */
00428             virtual std::vector<uint8_t> GetChannelRanges() = 0;
00429 
00430             /**
00431              * Set the time off air for the given duty band
00432              * @param band index
00433              * @param time off air in ms
00434              */
00435             virtual void SetDutyBandTimeOff(uint8_t band, uint32_t timeoff);
00436 
00437             /**
00438              * Get the time off air for the given duty band
00439              * @param band index
00440              * @return time off air in ms
00441              */
00442             virtual uint32_t GetDutyBandTimeOff(uint8_t band);
00443 
00444             /**
00445              * Get the number of duty bands in the current channel plan
00446              * @return number of bands
00447              */
00448             virtual uint8_t GetNumDutyBands();
00449 
00450             /**
00451              * Get the duty band index for the given frequency
00452              * @param freq frequency in Hz
00453              * @return index of duty band
00454              */
00455             virtual int8_t GetDutyBand(uint32_t freq);
00456 
00457             /**
00458              * Add duty band
00459              * @param index of duty band or -1 to append
00460              * @param band DutyBand definition
00461              * @return LORA_OK
00462              */
00463             virtual uint8_t AddDutyBand(int8_t index, DutyBand band);
00464 
00465             /**
00466              * Update duty cycle with current settings
00467              */
00468             void UpdateDutyCycle(uint8_t bytes);
00469 
00470             /**
00471              * Update duty cycle with at given frequency and time on air
00472              * @param freq frequency
00473              * @param time_on_air_ms tx time on air
00474              */
00475             virtual void UpdateDutyCycle(uint32_t freq, uint32_t time_on_air_ms);
00476 
00477             /**
00478              * Get time on air with current settings
00479              * @param bytes number of bytes to be sent
00480              * @param cfg for setting up the radio before getting time on air
00481              */
00482             virtual uint32_t GetTimeOnAir(uint8_t bytes, RadioCfg_t cfg = TX_RADIO_CFG);
00483 
00484             /**
00485              * Reset the duty timers with the current time off air
00486              */
00487             virtual void ResetDutyCycleTimer();
00488 
00489             /**
00490              * Print log message for given rx window
00491              * @param wnd 1 or 2
00492              */
00493             virtual void LogRxWindow(uint8_t wnd) = 0;
00494 
00495             /**
00496              * Indicator of P2P mode
00497              * @return true if enabled
00498              */
00499             virtual bool P2PEnabled();
00500 
00501             /**
00502              * Ack timeout for P2P mode
00503              * @return timeout in ms
00504              */
00505             virtual uint16_t P2PTimeout();
00506 
00507             /**
00508              * Ack backoff for P2P mode
00509              * @return backoff in ms
00510              */
00511             virtual uint16_t P2PBackoff();
00512 
00513             /**
00514              * Enable the default channels of the channel plan
00515              */
00516             virtual void EnableDefaultChannels() = 0;
00517 
00518             /**
00519              *  Callback for radio thread to signal
00520              */
00521             virtual void MacEvent();
00522 
00523             /**
00524              * Called when MAC layer doesn't know about a command.
00525              * Use to add custom or new mac command handling
00526              * @return LORA_OK
00527              */
00528             virtual uint8_t HandleMacCommand(uint8_t* payload, uint8_t& index);
00529 
00530             virtual void DecrementDatarate();
00531             virtual void IncrementDatarate();
00532 
00533             virtual std::string GetPlanName();
00534             virtual uint8_t GetPlan();
00535             virtual bool IsPlanFixed();
00536             virtual bool IsPlanDynamic();
00537             static bool IsPlanFixed(uint8_t plan);
00538             static bool IsPlanDynamic(uint8_t plan);
00539             virtual uint32_t GetMinFrequency();
00540             virtual uint32_t GetMaxFrequency();
00541 
00542             virtual uint8_t GetMinDatarate();
00543             virtual uint8_t GetMaxDatarate();
00544             virtual uint8_t GetMinDatarateOffset();
00545             virtual uint8_t GetMaxDatarateOffset();
00546 
00547             virtual uint8_t GetMinRx2Datarate();
00548             virtual uint8_t GetMaxRx2Datarate();
00549             virtual uint8_t GetMaxTxPower();
00550             virtual uint8_t GetMinTxPower();
00551 
00552             virtual uint16_t GetLBT_TimeUs();
00553             virtual void SetLBT_TimeUs(uint16_t us);
00554 
00555             virtual int8_t GetLBT_Threshold();
00556             virtual void SetLBT_Threshold(int8_t rssi);
00557 
00558             /**
00559              * Set LBT time and threshold to defaults
00560              */
00561             virtual void DefaultLBT();
00562 
00563             virtual bool ListenBeforeTalk();
00564         
00565             /**
00566              * use to clear downlink channels on join
00567              */
00568             virtual void ClearChannels();
00569 
00570             /**
00571              * Check if this packet is a beacon and if so extract parameters needed
00572              * @param payload of potential beacon
00573              * @param size of the packet
00574              * @param [out] data extracted from the beacon if this packet was indeed a beacon
00575              * @return true if this packet is beacon, false if not
00576              */
00577             virtual bool DecodeBeacon(const uint8_t* payload,
00578                                       size_t size,
00579                                       BeaconData_t& data) = 0;
00580 
00581             /**
00582              * Update class B beacon and ping slot settings if frequency hopping enabled
00583              * @param time received in the last beacon
00584              * @param period of the beacon
00585              * @param devAddr of this end device
00586              */
00587             virtual void FrequencyHop(uint32_t time, uint32_t period, uint32_t devAddr) { }
00588 
00589 
00590             /*
00591              * Get default number of channels for a plan
00592              */
00593             virtual uint8_t GetNumDefaultChans();
00594         protected:
00595 
00596             SxRadio* GetRadio();                //!< Get pointer to the SxRadio object or assert if it is null
00597             Settings* GetSettings();            //!< Get pointer to the settings object or assert if it is null
00598             /**
00599              * 16 bit ITU-T CRC implementation
00600              */
00601             uint16_t CRC16(const uint8_t* data, size_t size);
00602 
00603             uint8_t _txChannel;                 //!< Current channel for transmit
00604             uint8_t _txFrequencySubBand;        //!< Current frequency sub band for hybrid operation
00605 
00606             std::vector<Datarate> _datarates;   //!< List of datarates
00607 
00608             std::vector<Channel> _channels;     //!< List of channels for transmit
00609             std::vector<Channel> _dlChannels;   //!< List of channels for receive if changed from default
00610 
00611             std::vector<DutyBand> _dutyBands;   //!< List of duty bands to limit radio time on air
00612 
00613             uint8_t _maxTxPower;                //!< Max Tx power for channel Plan
00614             uint8_t _minTxPower;
00615 
00616             uint32_t _minFrequency;             //!< Minimum Frequency
00617             uint32_t _maxFrequency;             //!< Maximum Frequency
00618 
00619             uint8_t _minDatarate;               //!< Minimum datarate to accept in ADR request
00620             uint8_t _maxDatarate;               //!< Maximum datarate to accept in ADR request
00621 
00622             uint8_t _minRx2Datarate;            //!< Minimum datarate to accept in for Rx2
00623             uint8_t _maxRx2Datarate;            //!< Maximum datarate to accept in for Rx2
00624             uint8_t _minDatarateOffset;         //!< Minimum datarate offset to accept
00625             uint8_t _maxDatarateOffset;         //!< Maximum datarate offset to accept
00626 
00627             uint32_t _freqUBase125k;            //!< Start of 125K uplink channels
00628             uint32_t _freqUStep125k;            //!< Step between 125K uplink channels
00629             uint32_t _freqUBase500k;            //!< Start of 500K uplink channels
00630             uint32_t _freqUStep500k;            //!< Step between 500K uplink channels
00631             uint32_t _freqDBase500k;            //!< Start of 500K downlink channels
00632             uint32_t _freqDStep500k;            //!< Step between 500K downlink channels
00633 
00634             uint8_t _numChans;                  //!< Number of total channels in plan
00635             uint8_t _numChans125k;              //!< Number of 125K  channels in plan
00636             uint8_t _numChans500k;              //!< Number of 500K channels in plan
00637             uint8_t _numDefaultChans;           //!< Number of default channels in plan
00638             
00639             uint16_t _LBT_TimeUs;               //!< Sample time in us for LBT
00640             int8_t _LBT_Threshold;              //!< Threshold in dBm for LBT
00641 
00642             std::vector<uint16_t> _channelMask; //!< Bit mask for currently enabled channels
00643 
00644             Timer _dutyCycleTimer;              //!< Timer for tracking time-off-air
00645             int _txDutyEvtId;                   //!< Event ID for expiration of time-off-air
00646 
00647             bool _txDutyCyclePending;           //!< Flag for pending duty cycle event
00648 
00649             void OnTxDutyCycleEvent();          //!< Callback for duty cycle event
00650             void OnTxDutyCycleEventBottom();                    //!< Callback for duty cycle event
00651 
00652             static const uint8_t* TX_POWERS;                    //!< List of available tx powers
00653             static const uint8_t* RADIO_POWERS;                    //!< List of available tx powers
00654             static const uint8_t* MAX_PAYLOAD_SIZE;             //!< List of max payload sizes for each datarate
00655             static const uint8_t* MAX_PAYLOAD_SIZE_REPEATER;    //!< List of repeater compatible max payload sizes for each datarate
00656 
00657             uint8_t _plan;
00658             std::string _planName;
00659 
00660         private:
00661 
00662             SxRadio* _radio;                    //!< Injected SxRadio dependency
00663             Settings* _settings;                //!< Current settings
00664             EventQueue* _evtQueue;              //!< mbed Event Queue
00665     };
00666 }
00667 
00668 #endif