The Modified Dot Library for SX1272

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              * @param pad_ms time in milliseconds to add to computed window size
00269              * @return LORA_OK
00270              */
00271             virtual uint8_t SetRxConfig(uint8_t window,
00272                                         bool continuous,
00273                                         uint16_t wnd_growth = 1,
00274                                         uint16_t pad_ms = 0) = 0;
00275 
00276             /**
00277              * Set frequency sub band if supported by plan
00278              * @param sub_band
00279              * @return LORA_OK
00280              */
00281             virtual uint8_t SetFrequencySubBand(uint8_t group) = 0;
00282 
00283             /**
00284              * Get frequency sub band if supported by plan
00285              * @return sub band 0-8 or 0 if not supported
00286              */
00287             virtual uint8_t GetFrequencySubBand();
00288 
00289             /**
00290              * Reset the ack counter used to lower datarate if ACK's are missed
00291              */
00292             virtual void ResetAckCounter();
00293 
00294             /**
00295              * Callback for radio to request channel change when frequency hopping
00296              * @param currentChannel
00297              */
00298             virtual void FhssChangeChannel(uint8_t currentChannel);
00299 
00300             /**
00301              * Callback for ACK timeout event
00302              * @return LORA_OK
00303              */
00304             virtual uint8_t HandleAckTimeout();
00305 
00306             /**
00307              * Callback for Join Accept packet to load optional channels
00308              * @return LORA_OK
00309              */
00310             virtual uint8_t HandleJoinAccept(const uint8_t* buffer, uint8_t size) = 0;
00311 
00312             /**
00313              * Callback to for rx parameter setup ServerCommand
00314              * @param payload packet data
00315              * @param index of start of command buffer
00316              * @param size number of bytes in command buffer
00317              * @param[out] status to be returned in MoteCommand answer
00318              * @return LORA_OK
00319              */
00320             virtual uint8_t HandleRxParamSetup(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) = 0;
00321 
00322             /**
00323              * Callback to for new channel ServerCommand
00324              * @param payload packet data
00325              * @param index of start of command buffer
00326              * @param size number of bytes in command buffer
00327              * @param[out] status to be returned in MoteCommand answer
00328              * @return LORA_OK
00329              */
00330             virtual uint8_t HandleNewChannel(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) = 0;
00331 
00332             /**
00333              * Callback to for downlink channel request ServerCommand
00334              * @param payload packet data
00335              * @param index of start of command buffer
00336              * @param size number of bytes in command buffer
00337              * @param[out] status to be returned in MoteCommand answer
00338              * @return LORA_OK
00339              */
00340             virtual uint8_t HandleDownlinkChannelReq(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status);
00341 
00342             /**
00343              * Callback to for ping slot channel request ServerCommand
00344              * @param payload packet data
00345              * @param index of start of command buffer
00346              * @param size number of bytes in command buffer
00347              * @param[out] status to be returned in MoteCommand answer
00348              * @return LORA_OK
00349              */
00350             virtual uint8_t HandlePingSlotChannelReq(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) = 0;
00351 
00352             /**
00353              * Callback to for beacon frequency request ServerCommand
00354              * @param payload packet data
00355              * @param index of start of command buffer
00356              * @param size number of bytes in command buffer
00357              * @param[out] status to be returned in MoteCommand answer
00358              * @return LORA_OK
00359              */
00360             virtual uint8_t HandleBeaconFrequencyReq(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) = 0;
00361 
00362             /**
00363              * Callback to for adaptive datarate ServerCommand
00364              * @param payload packet data
00365              * @param index of start of command buffer
00366              * @param size number of bytes in command buffer
00367              * @param[out] status to be returned in MoteCommand answer
00368              * @return LORA_OK
00369              */
00370             virtual uint8_t HandleAdrCommand(const uint8_t* payload, uint8_t index, uint8_t size, uint8_t& status) = 0;
00371 
00372             /**
00373              * Validate the configuration after multiple ADR commands have been applied
00374              * @return status to be returned in MoteCommand answer
00375              */
00376             virtual uint8_t ValidateAdrConfiguration() = 0;
00377 
00378             /**
00379              * Check that Rf Frequency is within channel plan range
00380              * @param freq frequency in Hz
00381              * @return true if valid frequency
00382              */
00383             virtual bool CheckRfFrequency(uint32_t freq);
00384 
00385             /**
00386              * Flag for ADR
00387              * @return true if ADR is enable in settings
00388              */
00389             virtual bool IsAdrEnabled();
00390 
00391             /**
00392              * Flag if ADR ACK should be sent in next packet
00393              * @return true when flag should be set
00394              */
00395             virtual bool AdrAckReq();
00396 
00397             /**
00398              * Increment the ADR counter to track when ADR ACK request should be sent
00399              * @return current value
00400              */
00401             virtual uint8_t IncAdrCounter();
00402 
00403             /**
00404              * Reset the ADR counter when valid downlink is received from network server
00405              */
00406             virtual void ResetAdrCounter();
00407 
00408             /**
00409              * Get the time the radio must be off air to comply with regulations
00410              * Time to wait may be dependent on duty-cycle restrictions per channel
00411              * Or duty-cycle of join requests if OTAA is being attempted
00412              * @return ms of time to wait for next tx opportunity
00413              */
00414             virtual uint32_t GetTimeOffAir() = 0;
00415 
00416             /**
00417              * Get the channels in use by current channel plan
00418              * @return channel frequencies
00419              */
00420             virtual std::vector<uint32_t> GetChannels() = 0;
00421 
00422             /**
00423              * Get the downlink channels in use by current channel plan
00424              * @return channel frequencies
00425              */
00426             virtual std::vector<uint32_t> GetDownlinkChannels();
00427 
00428             /**
00429              * Get the channel datarate ranges in use by current channel plan
00430              * @return channel datarate ranges
00431              */
00432             virtual std::vector<uint8_t> GetChannelRanges() = 0;
00433 
00434             /**
00435              * Set the time off air for the given duty band
00436              * @param band index
00437              * @param time off air in ms
00438              */
00439             virtual void SetDutyBandTimeOff(uint8_t band, uint32_t timeoff);
00440 
00441             /**
00442              * Get the time off air for the given duty band
00443              * @param band index
00444              * @return time off air in ms
00445              */
00446             virtual uint32_t GetDutyBandTimeOff(uint8_t band);
00447 
00448             /**
00449              * Get the number of duty bands in the current channel plan
00450              * @return number of bands
00451              */
00452             virtual uint8_t GetNumDutyBands();
00453 
00454             /**
00455              * Get the duty band index for the given frequency
00456              * @param freq frequency in Hz
00457              * @return index of duty band
00458              */
00459             virtual int8_t GetDutyBand(uint32_t freq);
00460 
00461             /**
00462              * Add duty band
00463              * @param index of duty band or -1 to append
00464              * @param band DutyBand definition
00465              * @return LORA_OK
00466              */
00467             virtual uint8_t AddDutyBand(int8_t index, DutyBand band);
00468 
00469             /**
00470              * Update duty cycle with current settings
00471              */
00472             void UpdateDutyCycle(uint8_t bytes);
00473 
00474             /**
00475              * Update duty cycle with at given frequency and time on air
00476              * @param freq frequency
00477              * @param time_on_air_ms tx time on air
00478              */
00479             virtual void UpdateDutyCycle(uint32_t freq, uint32_t time_on_air_ms);
00480 
00481             /**
00482              * Get time on air with current settings
00483              * @param bytes number of bytes to be sent
00484              * @param cfg for setting up the radio before getting time on air
00485              */
00486             virtual uint32_t GetTimeOnAir(uint8_t bytes, RadioCfg_t cfg = TX_RADIO_CFG);
00487 
00488             /**
00489              * Reset the duty timers with the current time off air
00490              */
00491             virtual void ResetDutyCycleTimer();
00492 
00493             /**
00494              * Print log message for given rx window
00495              * @param wnd 1 or 2
00496              */
00497             virtual void LogRxWindow(uint8_t wnd) = 0;
00498 
00499             /**
00500              * Indicator of P2P mode
00501              * @return true if enabled
00502              */
00503             virtual bool P2PEnabled();
00504 
00505             /**
00506              * Ack timeout for P2P mode
00507              * @return timeout in ms
00508              */
00509             virtual uint16_t P2PTimeout();
00510 
00511             /**
00512              * Ack backoff for P2P mode
00513              * @return backoff in ms
00514              */
00515             virtual uint16_t P2PBackoff();
00516 
00517             /**
00518              * Enable the default channels of the channel plan
00519              */
00520             virtual void EnableDefaultChannels() = 0;
00521 
00522             /**
00523              *  Callback for radio thread to signal
00524              */
00525             virtual void MacEvent();
00526 
00527             /**
00528              * Called when MAC layer doesn't know about a command.
00529              * Use to add custom or new mac command handling
00530              * @return LORA_OK
00531              */
00532             virtual uint8_t HandleMacCommand(uint8_t* payload, uint8_t& index);
00533 
00534             virtual void DecrementDatarate();
00535             virtual void IncrementDatarate();
00536 
00537             virtual std::string GetPlanName();
00538             virtual uint8_t GetPlan();
00539             virtual bool IsPlanFixed();
00540             virtual bool IsPlanDynamic();
00541             static bool IsPlanFixed(uint8_t plan);
00542             static bool IsPlanDynamic(uint8_t plan);
00543             virtual uint32_t GetMinFrequency();
00544             virtual uint32_t GetMaxFrequency();
00545 
00546             virtual uint8_t GetMinDatarate();
00547             virtual uint8_t GetMaxDatarate();
00548             virtual uint8_t GetMinDatarateOffset();
00549             virtual uint8_t GetMaxDatarateOffset();
00550 
00551             virtual uint8_t GetMinRx2Datarate();
00552             virtual uint8_t GetMaxRx2Datarate();
00553             virtual uint8_t GetMaxTxPower();
00554             virtual uint8_t GetMinTxPower();
00555 
00556             virtual uint16_t GetLBT_TimeUs();
00557             virtual void SetLBT_TimeUs(uint16_t us);
00558 
00559             virtual int8_t GetLBT_Threshold();
00560             virtual void SetLBT_Threshold(int8_t rssi);
00561 
00562             /**
00563              * Set LBT time and threshold to defaults
00564              */
00565             virtual void DefaultLBT();
00566 
00567             virtual bool ListenBeforeTalk();
00568         
00569             /**
00570              * use to clear downlink channels on join
00571              */
00572             virtual void ClearChannels();
00573 
00574             /**
00575              * Check if this packet is a beacon and if so extract parameters needed
00576              * @param payload of potential beacon
00577              * @param size of the packet
00578              * @param [out] data extracted from the beacon if this packet was indeed a beacon
00579              * @return true if this packet is beacon, false if not
00580              */
00581             virtual bool DecodeBeacon(const uint8_t* payload,
00582                                       size_t size,
00583                                       BeaconData_t& data) = 0;
00584 
00585             /**
00586              * Update class B beacon and ping slot settings if frequency hopping enabled
00587              * @param time received in the last beacon
00588              * @param period of the beacon
00589              * @param devAddr of this end device
00590              */
00591             virtual void FrequencyHop(uint32_t time, uint32_t period, uint32_t devAddr) { }
00592 
00593 
00594             /*
00595              * Get default number of channels for a plan
00596              */
00597             virtual uint8_t GetNumDefaultChans();
00598         protected:
00599 
00600             SxRadio* GetRadio();                //!< Get pointer to the SxRadio object or assert if it is null
00601             Settings* GetSettings();            //!< Get pointer to the settings object or assert if it is null
00602             /**
00603              * 16 bit ITU-T CRC implementation
00604              */
00605             uint16_t CRC16(const uint8_t* data, size_t size);
00606 
00607             uint8_t _txChannel;                 //!< Current channel for transmit
00608             uint8_t _txFrequencySubBand;        //!< Current frequency sub band for hybrid operation
00609 
00610             std::vector<Datarate> _datarates;   //!< List of datarates
00611 
00612             std::vector<Channel> _channels;     //!< List of channels for transmit
00613             std::vector<Channel> _dlChannels;   //!< List of channels for receive if changed from default
00614 
00615             std::vector<DutyBand> _dutyBands;   //!< List of duty bands to limit radio time on air
00616 
00617             uint8_t _maxTxPower;                //!< Max Tx power for channel Plan
00618             uint8_t _minTxPower;
00619 
00620             uint32_t _minFrequency;             //!< Minimum Frequency
00621             uint32_t _maxFrequency;             //!< Maximum Frequency
00622 
00623             uint8_t _minDatarate;               //!< Minimum datarate to accept in ADR request
00624             uint8_t _maxDatarate;               //!< Maximum datarate to accept in ADR request
00625 
00626             uint8_t _minRx2Datarate;            //!< Minimum datarate to accept in for Rx2
00627             uint8_t _maxRx2Datarate;            //!< Maximum datarate to accept in for Rx2
00628             uint8_t _minDatarateOffset;         //!< Minimum datarate offset to accept
00629             uint8_t _maxDatarateOffset;         //!< Maximum datarate offset to accept
00630 
00631             uint32_t _freqUBase125k;            //!< Start of 125K uplink channels
00632             uint32_t _freqUStep125k;            //!< Step between 125K uplink channels
00633             uint32_t _freqUBase500k;            //!< Start of 500K uplink channels
00634             uint32_t _freqUStep500k;            //!< Step between 500K uplink channels
00635             uint32_t _freqDBase500k;            //!< Start of 500K downlink channels
00636             uint32_t _freqDStep500k;            //!< Step between 500K downlink channels
00637 
00638             uint8_t _numChans;                  //!< Number of total channels in plan
00639             uint8_t _numChans125k;              //!< Number of 125K  channels in plan
00640             uint8_t _numChans500k;              //!< Number of 500K channels in plan
00641             uint8_t _numDefaultChans;           //!< Number of default channels in plan
00642             
00643             uint16_t _LBT_TimeUs;               //!< Sample time in us for LBT
00644             int8_t _LBT_Threshold;              //!< Threshold in dBm for LBT
00645 
00646             std::vector<uint16_t> _channelMask; //!< Bit mask for currently enabled channels
00647 
00648             Timer _dutyCycleTimer;              //!< Timer for tracking time-off-air
00649             int _txDutyEvtId;                   //!< Event ID for expiration of time-off-air
00650 
00651             bool _txDutyCyclePending;           //!< Flag for pending duty cycle event
00652 
00653             void OnTxDutyCycleEvent();          //!< Callback for duty cycle event
00654             void OnTxDutyCycleEventBottom();                    //!< Callback for duty cycle event
00655 
00656             static const uint8_t* TX_POWERS;                    //!< List of available tx powers
00657             static const uint8_t* RADIO_POWERS;                    //!< List of available tx powers
00658             static const uint8_t* MAX_PAYLOAD_SIZE;             //!< List of max payload sizes for each datarate
00659             static const uint8_t* MAX_PAYLOAD_SIZE_REPEATER;    //!< List of repeater compatible max payload sizes for each datarate
00660 
00661             uint8_t _plan;
00662             std::string _planName;
00663 
00664         private:
00665 
00666             SxRadio* _radio;                    //!< Injected SxRadio dependency
00667             Settings* _settings;                //!< Current settings
00668             EventQueue* _evtQueue;              //!< mbed Event Queue
00669     };
00670 }
00671 
00672 #endif