Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 00599 /* 00600 * Search enabled channels for lowest available datarate 00601 */ 00602 virtual uint8_t GetMinEnabledDatarate(); 00603 protected: 00604 00605 SxRadio* GetRadio(); //!< Get pointer to the SxRadio object or assert if it is null 00606 Settings* GetSettings(); //!< Get pointer to the settings object or assert if it is null 00607 /** 00608 * 16 bit ITU-T CRC implementation 00609 */ 00610 uint16_t CRC16(const uint8_t* data, size_t size); 00611 00612 uint8_t _txChannel; //!< Current channel for transmit 00613 uint8_t _txFrequencySubBand; //!< Current frequency sub band for hybrid operation 00614 00615 std::vector<Datarate> _datarates; //!< List of datarates 00616 00617 std::vector<Channel> _channels; //!< List of channels for transmit 00618 std::vector<Channel> _dlChannels; //!< List of channels for receive if changed from default 00619 00620 std::vector<DutyBand> _dutyBands; //!< List of duty bands to limit radio time on air 00621 00622 uint8_t _maxTxPower; //!< Max Tx power for channel Plan 00623 uint8_t _minTxPower; 00624 00625 uint32_t _minFrequency; //!< Minimum Frequency 00626 uint32_t _maxFrequency; //!< Maximum Frequency 00627 00628 uint8_t _minDatarate; //!< Minimum datarate to accept in ADR request 00629 uint8_t _maxDatarate; //!< Maximum datarate to accept in ADR request 00630 00631 uint8_t _minRx2Datarate; //!< Minimum datarate to accept in for Rx2 00632 uint8_t _maxRx2Datarate; //!< Maximum datarate to accept in for Rx2 00633 uint8_t _minDatarateOffset; //!< Minimum datarate offset to accept 00634 uint8_t _maxDatarateOffset; //!< Maximum datarate offset to accept 00635 00636 uint32_t _freqUBase125k; //!< Start of 125K uplink channels 00637 uint32_t _freqUStep125k; //!< Step between 125K uplink channels 00638 uint32_t _freqUBase500k; //!< Start of 500K uplink channels 00639 uint32_t _freqUStep500k; //!< Step between 500K uplink channels 00640 uint32_t _freqDBase500k; //!< Start of 500K downlink channels 00641 uint32_t _freqDStep500k; //!< Step between 500K downlink channels 00642 00643 uint8_t _numChans; //!< Number of total channels in plan 00644 uint8_t _numChans125k; //!< Number of 125K channels in plan 00645 uint8_t _numChans500k; //!< Number of 500K channels in plan 00646 uint8_t _numDefaultChans; //!< Number of default channels in plan 00647 00648 uint16_t _LBT_TimeUs; //!< Sample time in us for LBT 00649 int8_t _LBT_Threshold; //!< Threshold in dBm for LBT 00650 00651 std::vector<uint16_t> _channelMask; //!< Bit mask for currently enabled channels 00652 00653 Timer _dutyCycleTimer; //!< Timer for tracking time-off-air 00654 int _txDutyEvtId; //!< Event ID for expiration of time-off-air 00655 00656 bool _txDutyCyclePending; //!< Flag for pending duty cycle event 00657 00658 void OnTxDutyCycleEvent(); //!< Callback for duty cycle event 00659 void OnTxDutyCycleEventBottom(); //!< Callback for duty cycle event 00660 00661 static const uint8_t* TX_POWERS; //!< List of available tx powers 00662 static const uint8_t* RADIO_POWERS; //!< List of available tx powers 00663 static const uint8_t* MAX_PAYLOAD_SIZE; //!< List of max payload sizes for each datarate 00664 static const uint8_t* MAX_PAYLOAD_SIZE_REPEATER; //!< List of repeater compatible max payload sizes for each datarate 00665 00666 uint8_t _plan; 00667 std::string _planName; 00668 00669 private: 00670 00671 SxRadio* _radio; //!< Injected SxRadio dependency 00672 Settings* _settings; //!< Current settings 00673 EventQueue* _evtQueue; //!< mbed Event Queue 00674 }; 00675 } 00676 00677 #endif
Generated on Fri Jul 15 2022 21:40:31 by
1.7.2