Senet / LoRaWAN-lib

Fork of LoRaWAN-lib by canuck lehead

Committer:
Shaun Nelson
Date:
Tue Aug 15 17:10:25 2017 -0400
Branch:
class_b
Revision:
40:f7ce84dc9363
Parent:
38:182ba91524e4
Child:
48:81c0f4c4dd2c
Add debug state

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Shaun Nelson 38:182ba91524e4 1 /*
Shaun Nelson 38:182ba91524e4 2 / _____) _ | |
Shaun Nelson 38:182ba91524e4 3 ( (____ _____ ____ _| |_ _____ ____| |__
Shaun Nelson 38:182ba91524e4 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
Shaun Nelson 38:182ba91524e4 5 _____) ) ____| | | || |_| ____( (___| | | |
Shaun Nelson 38:182ba91524e4 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
Shaun Nelson 38:182ba91524e4 7 (C)2013 Semtech
Shaun Nelson 38:182ba91524e4 8 ___ _____ _ ___ _ _____ ___ ___ ___ ___
Shaun Nelson 38:182ba91524e4 9 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
Shaun Nelson 38:182ba91524e4 10 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
Shaun Nelson 38:182ba91524e4 11 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
Shaun Nelson 38:182ba91524e4 12 embedded.connectivity.solutions===============
Shaun Nelson 38:182ba91524e4 13
Shaun Nelson 38:182ba91524e4 14 Description: LoRa MAC Class B layer implementation
Shaun Nelson 38:182ba91524e4 15
Shaun Nelson 38:182ba91524e4 16 License: Revised BSD License, see LICENSE.TXT file include in the project
Shaun Nelson 38:182ba91524e4 17
Shaun Nelson 38:182ba91524e4 18 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
Shaun Nelson 38:182ba91524e4 19 */
Shaun Nelson 38:182ba91524e4 20 #include "board.h"
Shaun Nelson 38:182ba91524e4 21 #include "LoRaMac.h"
Shaun Nelson 38:182ba91524e4 22 #include "region/Region.h"
Shaun Nelson 38:182ba91524e4 23 #include "LoRaMacClassB.h"
Shaun Nelson 38:182ba91524e4 24 #include "LoRaMacCrypto.h"
Shaun Nelson 38:182ba91524e4 25
Shaun Nelson 38:182ba91524e4 26 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 27 /*!
Shaun Nelson 38:182ba91524e4 28 * State of the beaconing mechanism
Shaun Nelson 38:182ba91524e4 29 */
Shaun Nelson 38:182ba91524e4 30 static BeaconState_t BeaconState;
Shaun Nelson 38:182ba91524e4 31
Shaun Nelson 38:182ba91524e4 32 /*!
Shaun Nelson 38:182ba91524e4 33 * State of the ping slot mechanism
Shaun Nelson 38:182ba91524e4 34 */
Shaun Nelson 38:182ba91524e4 35 static PingSlotState_t PingSlotState;
Shaun Nelson 38:182ba91524e4 36
Shaun Nelson 38:182ba91524e4 37 /*!
Shaun Nelson 38:182ba91524e4 38 * State of the multicast slot mechanism
Shaun Nelson 38:182ba91524e4 39 */
Shaun Nelson 38:182ba91524e4 40 static PingSlotState_t MulticastSlotState;
Shaun Nelson 38:182ba91524e4 41
Shaun Nelson 38:182ba91524e4 42 /*!
Shaun Nelson 38:182ba91524e4 43 * Class B ping slot context
Shaun Nelson 38:182ba91524e4 44 */
Shaun Nelson 38:182ba91524e4 45 static PingSlotContext_t PingSlotCtx;
Shaun Nelson 38:182ba91524e4 46
Shaun Nelson 38:182ba91524e4 47 /*!
Shaun Nelson 38:182ba91524e4 48 * Class B beacon context
Shaun Nelson 38:182ba91524e4 49 */
Shaun Nelson 40:f7ce84dc9363 50 BeaconContext_t BeaconCtx;
Shaun Nelson 38:182ba91524e4 51
Shaun Nelson 38:182ba91524e4 52 /*!
Shaun Nelson 38:182ba91524e4 53 * Timer for CLASS B beacon acquisition and tracking.
Shaun Nelson 38:182ba91524e4 54 */
Shaun Nelson 38:182ba91524e4 55 static TimerEvent_t BeaconTimer;
Shaun Nelson 38:182ba91524e4 56
Shaun Nelson 38:182ba91524e4 57 /*!
Shaun Nelson 38:182ba91524e4 58 * Timer for CLASS B ping slot timer.
Shaun Nelson 38:182ba91524e4 59 */
Shaun Nelson 38:182ba91524e4 60 static TimerEvent_t PingSlotTimer;
Shaun Nelson 38:182ba91524e4 61
Shaun Nelson 38:182ba91524e4 62 /*!
Shaun Nelson 38:182ba91524e4 63 * Timer for CLASS B multicast ping slot timer.
Shaun Nelson 38:182ba91524e4 64 */
Shaun Nelson 38:182ba91524e4 65 static TimerEvent_t MulticastSlotTimer;
Shaun Nelson 38:182ba91524e4 66
Shaun Nelson 38:182ba91524e4 67 /*!
Shaun Nelson 38:182ba91524e4 68 * Container for the callbacks related to class b.
Shaun Nelson 38:182ba91524e4 69 */
Shaun Nelson 38:182ba91524e4 70 static LoRaMacClassBCallback_t LoRaMacClassBCallbacks;
Shaun Nelson 38:182ba91524e4 71
Shaun Nelson 38:182ba91524e4 72 /*!
Shaun Nelson 38:182ba91524e4 73 * Data structure which holds the parameters which needs to be set
Shaun Nelson 38:182ba91524e4 74 * in class b operation.
Shaun Nelson 38:182ba91524e4 75 */
Shaun Nelson 38:182ba91524e4 76 static LoRaMacClassBParams_t LoRaMacClassBParams;
Shaun Nelson 38:182ba91524e4 77
Shaun Nelson 38:182ba91524e4 78
Shaun Nelson 38:182ba91524e4 79 /*!
Shaun Nelson 38:182ba91524e4 80 * \brief Calculates the next ping slot time.
Shaun Nelson 38:182ba91524e4 81 *
Shaun Nelson 38:182ba91524e4 82 * \param [IN] slotOffset The ping slot offset
Shaun Nelson 38:182ba91524e4 83 * \param [IN] pingPeriod The ping period
Shaun Nelson 38:182ba91524e4 84 * \param [OUT] timeOffset Time offset of the next slot, based on current time
Shaun Nelson 38:182ba91524e4 85 *
Shaun Nelson 38:182ba91524e4 86 * \retval [true: ping slot found, false: no ping slot found]
Shaun Nelson 38:182ba91524e4 87 */
Shaun Nelson 38:182ba91524e4 88 static bool CalcNextSlotTime( uint16_t slotOffset, uint16_t pingPeriod, TimerTime_t* timeOffset )
Shaun Nelson 38:182ba91524e4 89 {
Shaun Nelson 38:182ba91524e4 90 uint8_t currentPingSlot = 0;
Shaun Nelson 38:182ba91524e4 91 TimerTime_t slotTime = 0;
Shaun Nelson 38:182ba91524e4 92 TimerTime_t currentTime = TimerGetCurrentTime( );
Shaun Nelson 38:182ba91524e4 93
Shaun Nelson 38:182ba91524e4 94 // Calculate the point in time of the last beacon even if we missed it
Shaun Nelson 38:182ba91524e4 95 slotTime = ( ( currentTime - BeaconCtx.LastBeaconRx ) % BeaconCtx.Cfg.Interval );
Shaun Nelson 38:182ba91524e4 96 slotTime = currentTime - slotTime;
Shaun Nelson 38:182ba91524e4 97
Shaun Nelson 38:182ba91524e4 98 // Add the reserved time and the ping offset
Shaun Nelson 38:182ba91524e4 99 slotTime += BeaconCtx.Cfg.Reserved;
Shaun Nelson 38:182ba91524e4 100 slotTime += slotOffset * PingSlotCtx.Cfg.PingSlotWindow;
Shaun Nelson 38:182ba91524e4 101
Shaun Nelson 38:182ba91524e4 102 if( slotTime < currentTime )
Shaun Nelson 38:182ba91524e4 103 {
Shaun Nelson 38:182ba91524e4 104 currentPingSlot = ( ( currentTime - slotTime ) /
Shaun Nelson 38:182ba91524e4 105 ( pingPeriod * PingSlotCtx.Cfg.PingSlotWindow ) ) + 1;
Shaun Nelson 38:182ba91524e4 106 slotTime += ( ( TimerTime_t )( currentPingSlot * pingPeriod ) *
Shaun Nelson 38:182ba91524e4 107 PingSlotCtx.Cfg.PingSlotWindow );
Shaun Nelson 38:182ba91524e4 108 }
Shaun Nelson 38:182ba91524e4 109
Shaun Nelson 38:182ba91524e4 110 if( currentPingSlot < PingSlotCtx.PingNb )
Shaun Nelson 38:182ba91524e4 111 {
Shaun Nelson 38:182ba91524e4 112 if( slotTime <= ( BeaconCtx.NextBeaconRx - BeaconCtx.Cfg.Guard - PingSlotCtx.Cfg.PingSlotWindow ) )
Shaun Nelson 38:182ba91524e4 113 {
Shaun Nelson 38:182ba91524e4 114 // Calculate the relative ping slot time
Shaun Nelson 38:182ba91524e4 115 slotTime -= currentTime;
Shaun Nelson 38:182ba91524e4 116 slotTime -= RADIO_WAKEUP_TIME;
Shaun Nelson 38:182ba91524e4 117 slotTime = TimerTempCompensation( slotTime, BeaconCtx.Temperature );
Shaun Nelson 38:182ba91524e4 118 *timeOffset = slotTime;
Shaun Nelson 38:182ba91524e4 119 return true;
Shaun Nelson 38:182ba91524e4 120 }
Shaun Nelson 38:182ba91524e4 121 }
Shaun Nelson 38:182ba91524e4 122 return false;
Shaun Nelson 38:182ba91524e4 123 }
Shaun Nelson 38:182ba91524e4 124
Shaun Nelson 38:182ba91524e4 125 /*!
Shaun Nelson 38:182ba91524e4 126 * \brief Calculates CRC's of the beacon frame
Shaun Nelson 38:182ba91524e4 127 *
Shaun Nelson 38:182ba91524e4 128 * \param [IN] buffer Pointer to the data
Shaun Nelson 38:182ba91524e4 129 * \param [IN] length Length of the data
Shaun Nelson 38:182ba91524e4 130 *
Shaun Nelson 38:182ba91524e4 131 * \retval CRC
Shaun Nelson 38:182ba91524e4 132 */
Shaun Nelson 38:182ba91524e4 133 static uint16_t BeaconCrc( uint8_t *buffer, uint16_t length )
Shaun Nelson 38:182ba91524e4 134 {
Shaun Nelson 38:182ba91524e4 135 // The CRC calculation follows CCITT
Shaun Nelson 38:182ba91524e4 136 const uint16_t polynom = 0x1021;
Shaun Nelson 38:182ba91524e4 137 // CRC initial value
Shaun Nelson 38:182ba91524e4 138 uint16_t crc = 0x0000;
Shaun Nelson 38:182ba91524e4 139
Shaun Nelson 38:182ba91524e4 140 if( buffer == NULL )
Shaun Nelson 38:182ba91524e4 141 {
Shaun Nelson 38:182ba91524e4 142 return 0;
Shaun Nelson 38:182ba91524e4 143 }
Shaun Nelson 38:182ba91524e4 144
Shaun Nelson 38:182ba91524e4 145 for( uint16_t i = 0; i < length; ++i )
Shaun Nelson 38:182ba91524e4 146 {
Shaun Nelson 38:182ba91524e4 147 crc ^= ( uint16_t ) buffer[i] << 8;
Shaun Nelson 38:182ba91524e4 148 for( uint16_t j = 0; j < 8; ++j )
Shaun Nelson 38:182ba91524e4 149 {
Shaun Nelson 38:182ba91524e4 150 crc = ( crc & 0x8000 ) ? ( crc << 1 ) ^ polynom : ( crc << 1 );
Shaun Nelson 38:182ba91524e4 151 }
Shaun Nelson 38:182ba91524e4 152 }
Shaun Nelson 38:182ba91524e4 153
Shaun Nelson 38:182ba91524e4 154 return crc;
Shaun Nelson 38:182ba91524e4 155 }
Shaun Nelson 38:182ba91524e4 156
Shaun Nelson 38:182ba91524e4 157 static void GetTemperatureLevel( LoRaMacClassBCallback_t *callbacks, BeaconContext_t *beaconCtx )
Shaun Nelson 38:182ba91524e4 158 {
Shaun Nelson 38:182ba91524e4 159 // Measure temperature, if available
Shaun Nelson 38:182ba91524e4 160 if( ( callbacks != NULL ) && ( callbacks->GetTemperatureLevel != NULL ) )
Shaun Nelson 38:182ba91524e4 161 {
Shaun Nelson 38:182ba91524e4 162 beaconCtx->Temperature = callbacks->GetTemperatureLevel( );
Shaun Nelson 38:182ba91524e4 163 }
Shaun Nelson 38:182ba91524e4 164 }
Shaun Nelson 38:182ba91524e4 165
Shaun Nelson 38:182ba91524e4 166 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 167
Shaun Nelson 38:182ba91524e4 168 void LoRaMacClassBInit( LoRaMacClassBParams_t *classBParams, LoRaMacClassBCallback_t *callbacks )
Shaun Nelson 38:182ba91524e4 169 {
Shaun Nelson 38:182ba91524e4 170 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 171 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 172 PhyParam_t phyParam;
Shaun Nelson 38:182ba91524e4 173
Shaun Nelson 38:182ba91524e4 174 // Init variables to default
Shaun Nelson 38:182ba91524e4 175 memset1( ( uint8_t* ) &BeaconCtx, 0, sizeof( BeaconContext_t ) );
Shaun Nelson 38:182ba91524e4 176 memset1( ( uint8_t* ) &PingSlotCtx, 0, sizeof( PingSlotCtx ) );
Shaun Nelson 38:182ba91524e4 177
Shaun Nelson 38:182ba91524e4 178 // Store callbacks
Shaun Nelson 38:182ba91524e4 179 LoRaMacClassBCallbacks = *callbacks;
Shaun Nelson 38:182ba91524e4 180
Shaun Nelson 38:182ba91524e4 181 // Store parameter pointers
Shaun Nelson 38:182ba91524e4 182 LoRaMacClassBParams = *classBParams;
Shaun Nelson 38:182ba91524e4 183
Shaun Nelson 38:182ba91524e4 184 // Setup default temperature
Shaun Nelson 38:182ba91524e4 185 BeaconCtx.Temperature = 25.0;
Shaun Nelson 38:182ba91524e4 186 GetTemperatureLevel( &LoRaMacClassBCallbacks, &BeaconCtx );
Shaun Nelson 38:182ba91524e4 187
Shaun Nelson 38:182ba91524e4 188 // Initialize timers
Shaun Nelson 38:182ba91524e4 189 TimerInit( &BeaconTimer, LoRaMacClassBBeaconTimerEvent );
Shaun Nelson 38:182ba91524e4 190 TimerInit( &PingSlotTimer, LoRaMacClassBPingSlotTimerEvent );
Shaun Nelson 38:182ba91524e4 191 TimerInit( &MulticastSlotTimer, LoRaMacClassBMulticastSlotTimerEvent );
Shaun Nelson 38:182ba91524e4 192
Shaun Nelson 38:182ba91524e4 193 // Setup default states
Shaun Nelson 38:182ba91524e4 194 BeaconState = BEACON_STATE_ACQUISITION;
Shaun Nelson 38:182ba91524e4 195 PingSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 196 MulticastSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 197
Shaun Nelson 38:182ba91524e4 198 // Get phy parameters
Shaun Nelson 38:182ba91524e4 199 getPhy.Attribute = PHY_BEACON_INTERVAL;
Shaun Nelson 38:182ba91524e4 200 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 201 BeaconCtx.Cfg.Interval = phyParam.Value;
Shaun Nelson 38:182ba91524e4 202
Shaun Nelson 38:182ba91524e4 203 getPhy.Attribute = PHY_BEACON_RESERVED;
Shaun Nelson 38:182ba91524e4 204 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 205 BeaconCtx.Cfg.Reserved = phyParam.Value;
Shaun Nelson 38:182ba91524e4 206
Shaun Nelson 38:182ba91524e4 207 getPhy.Attribute = PHY_BEACON_GUARD;
Shaun Nelson 38:182ba91524e4 208 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 209 BeaconCtx.Cfg.Guard = phyParam.Value;
Shaun Nelson 38:182ba91524e4 210
Shaun Nelson 38:182ba91524e4 211 getPhy.Attribute = PHY_BEACON_WINDOW;
Shaun Nelson 38:182ba91524e4 212 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 213 BeaconCtx.Cfg.Window = phyParam.Value;
Shaun Nelson 38:182ba91524e4 214
Shaun Nelson 38:182ba91524e4 215 getPhy.Attribute = PHY_BEACON_WINDOW_SLOTS;
Shaun Nelson 38:182ba91524e4 216 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 217 BeaconCtx.Cfg.WindowSlots = phyParam.Value;
Shaun Nelson 38:182ba91524e4 218
Shaun Nelson 38:182ba91524e4 219 getPhy.Attribute = PHY_BEACON_SYMBOL_TO_DEFAULT;
Shaun Nelson 38:182ba91524e4 220 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 221 BeaconCtx.Cfg.SymbolToDefault = phyParam.Value;
Shaun Nelson 38:182ba91524e4 222
Shaun Nelson 38:182ba91524e4 223 getPhy.Attribute = PHY_BEACON_SYMBOL_TO_EXPANSION_MAX;
Shaun Nelson 38:182ba91524e4 224 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 225 BeaconCtx.Cfg.SymbolToExpansionMax = phyParam.Value;
Shaun Nelson 38:182ba91524e4 226
Shaun Nelson 38:182ba91524e4 227 getPhy.Attribute = PHY_BEACON_SYMBOL_TO_EXPANSION_FACTOR;
Shaun Nelson 38:182ba91524e4 228 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 229 BeaconCtx.Cfg.SymbolToExpansionFactor = phyParam.Value;
Shaun Nelson 38:182ba91524e4 230
Shaun Nelson 38:182ba91524e4 231 getPhy.Attribute = PHY_MAX_BEACON_LESS_PERIOD;
Shaun Nelson 38:182ba91524e4 232 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 233 BeaconCtx.Cfg.MaxBeaconLessPeriod = phyParam.Value;
Shaun Nelson 38:182ba91524e4 234
Shaun Nelson 38:182ba91524e4 235 getPhy.Attribute = PHY_BEACON_DELAY_BEACON_TIMING_ANS;
Shaun Nelson 38:182ba91524e4 236 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 237 BeaconCtx.Cfg.DelayBeaconTimingAns = phyParam.Value;
Shaun Nelson 38:182ba91524e4 238
Shaun Nelson 38:182ba91524e4 239 getPhy.Attribute = PHY_PING_SLOT_WINDOW;
Shaun Nelson 38:182ba91524e4 240 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 241 PingSlotCtx.Cfg.PingSlotWindow = phyParam.Value;
Shaun Nelson 38:182ba91524e4 242
Shaun Nelson 38:182ba91524e4 243 getPhy.Attribute = PHY_PING_SLOT_SYMBOL_TO_EXPANSION_MAX;
Shaun Nelson 38:182ba91524e4 244 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 245 PingSlotCtx.Cfg.SymbolToExpansionMax = phyParam.Value;
Shaun Nelson 38:182ba91524e4 246
Shaun Nelson 38:182ba91524e4 247 getPhy.Attribute = PHY_PING_SLOT_SYMBOL_TO_EXPANSION_FACTOR;
Shaun Nelson 38:182ba91524e4 248 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 249 PingSlotCtx.Cfg.SymbolToExpansionFactor = phyParam.Value;
Shaun Nelson 38:182ba91524e4 250 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 251 }
Shaun Nelson 38:182ba91524e4 252
Shaun Nelson 38:182ba91524e4 253 void LoRaMacClassBSetBeaconState( BeaconState_t beaconState )
Shaun Nelson 38:182ba91524e4 254 {
Shaun Nelson 38:182ba91524e4 255 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 256 BeaconState = beaconState;
Shaun Nelson 38:182ba91524e4 257 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 258 }
Shaun Nelson 38:182ba91524e4 259
Shaun Nelson 38:182ba91524e4 260 void LoRaMacClassBSetPingSlotState( PingSlotState_t pingSlotState )
Shaun Nelson 38:182ba91524e4 261 {
Shaun Nelson 38:182ba91524e4 262 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 263 PingSlotState = pingSlotState;
Shaun Nelson 38:182ba91524e4 264 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 265 }
Shaun Nelson 38:182ba91524e4 266
Shaun Nelson 40:f7ce84dc9363 267 static TimerTime_t BeaconEventTime = 0;
Shaun Nelson 40:f7ce84dc9363 268
Shaun Nelson 40:f7ce84dc9363 269 TimerTime_t LoRaMacClassBGetBeaconEventTime( )
Shaun Nelson 40:f7ce84dc9363 270 {
Shaun Nelson 40:f7ce84dc9363 271 return BeaconEventTime;
Shaun Nelson 40:f7ce84dc9363 272 }
Shaun Nelson 40:f7ce84dc9363 273
Shaun Nelson 38:182ba91524e4 274 void LoRaMacClassBBeaconTimerEvent( void )
Shaun Nelson 38:182ba91524e4 275 {
Shaun Nelson 38:182ba91524e4 276 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 277 RxBeaconSetup_t rxBeaconSetup;
Shaun Nelson 38:182ba91524e4 278 bool beaconChannelSet = false;
Shaun Nelson 38:182ba91524e4 279 uint8_t index = 0;
Shaun Nelson 38:182ba91524e4 280 bool activateTimer = false;
Shaun Nelson 38:182ba91524e4 281 TimerTime_t beaconEventTime = 1;
Shaun Nelson 38:182ba91524e4 282 TimerTime_t currentTime = TimerGetCurrentTime( );
Shaun Nelson 38:182ba91524e4 283
Shaun Nelson 38:182ba91524e4 284 TimerStop( &BeaconTimer );
Shaun Nelson 40:f7ce84dc9363 285 BeaconEventTime = 0;
Shaun Nelson 38:182ba91524e4 286
Shaun Nelson 38:182ba91524e4 287 // Beacon state machine
Shaun Nelson 38:182ba91524e4 288 switch( BeaconState )
Shaun Nelson 38:182ba91524e4 289 {
Shaun Nelson 38:182ba91524e4 290 case BEACON_STATE_ACQUISITION:
Shaun Nelson 38:182ba91524e4 291 {
Shaun Nelson 38:182ba91524e4 292 activateTimer = true;
Shaun Nelson 38:182ba91524e4 293
Shaun Nelson 38:182ba91524e4 294 if( BeaconCtx.Ctrl.AcquisitionPending == 1 )
Shaun Nelson 38:182ba91524e4 295 {
Shaun Nelson 38:182ba91524e4 296 Radio.Sleep();
Shaun Nelson 38:182ba91524e4 297 BeaconState = BEACON_STATE_SWITCH_CLASS;
Shaun Nelson 38:182ba91524e4 298 }
Shaun Nelson 38:182ba91524e4 299 else
Shaun Nelson 38:182ba91524e4 300 {
Shaun Nelson 38:182ba91524e4 301 // Default symbol timeouts
Shaun Nelson 38:182ba91524e4 302 BeaconCtx.SymbolTimeout = BeaconCtx.Cfg.SymbolToDefault;
Shaun Nelson 38:182ba91524e4 303 PingSlotCtx.SymbolTimeout = BeaconCtx.Cfg.SymbolToDefault;
Shaun Nelson 38:182ba91524e4 304
Shaun Nelson 38:182ba91524e4 305 if( BeaconCtx.Ctrl.BeaconDelaySet == 1 )
Shaun Nelson 38:182ba91524e4 306 {
Shaun Nelson 38:182ba91524e4 307 if( BeaconCtx.BeaconTimingDelay > 0 )
Shaun Nelson 38:182ba91524e4 308 {
Shaun Nelson 38:182ba91524e4 309 if( BeaconCtx.NextBeaconRx > currentTime )
Shaun Nelson 38:182ba91524e4 310 {
Shaun Nelson 38:182ba91524e4 311 BeaconCtx.Ctrl.AcquisitionTimerSet = 1;
Shaun Nelson 38:182ba91524e4 312 beaconEventTime = TimerTempCompensation( BeaconCtx.NextBeaconRx - currentTime, BeaconCtx.Temperature );
Shaun Nelson 38:182ba91524e4 313 }
Shaun Nelson 38:182ba91524e4 314 else
Shaun Nelson 38:182ba91524e4 315 {
Shaun Nelson 38:182ba91524e4 316 BeaconCtx.Ctrl.BeaconDelaySet = 0;
Shaun Nelson 38:182ba91524e4 317 BeaconCtx.Ctrl.AcquisitionPending = 1;
Shaun Nelson 38:182ba91524e4 318 BeaconCtx.Ctrl.AcquisitionTimerSet = 0;
Shaun Nelson 38:182ba91524e4 319 beaconEventTime = BeaconCtx.Cfg.Interval;
Shaun Nelson 38:182ba91524e4 320
Shaun Nelson 38:182ba91524e4 321 rxBeaconSetup.SymbolTimeout = BeaconCtx.SymbolTimeout;
Shaun Nelson 38:182ba91524e4 322 rxBeaconSetup.RxTime = 0;
Shaun Nelson 38:182ba91524e4 323 rxBeaconSetup.DeviceAddress = *LoRaMacClassBParams.LoRaMacDevAddr;
Shaun Nelson 38:182ba91524e4 324 rxBeaconSetup.BeaconTimingChannel = BeaconCtx.BeaconTimingChannel;
Shaun Nelson 38:182ba91524e4 325 rxBeaconSetup.CustomFrequencyEnabled = BeaconCtx.Ctrl.CustomFreq;
Shaun Nelson 38:182ba91524e4 326 rxBeaconSetup.BeaconChannelSet = BeaconCtx.Ctrl.BeaconChannelSet;
Shaun Nelson 38:182ba91524e4 327 rxBeaconSetup.CustomFrequency = BeaconCtx.Frequency;
Shaun Nelson 38:182ba91524e4 328 rxBeaconSetup.BeaconTime = BeaconCtx.BeaconTime;
Shaun Nelson 38:182ba91524e4 329 rxBeaconSetup.BeaconInterval = BeaconCtx.Cfg.Interval;
Shaun Nelson 38:182ba91524e4 330
Shaun Nelson 38:182ba91524e4 331 RegionRxBeaconSetup( *LoRaMacClassBParams.LoRaMacRegion, &rxBeaconSetup, &LoRaMacClassBParams.McpsIndication->RxDatarate, &beaconChannelSet );
Shaun Nelson 38:182ba91524e4 332 BeaconCtx.Ctrl.BeaconChannelSet = beaconChannelSet;
Shaun Nelson 38:182ba91524e4 333 }
Shaun Nelson 38:182ba91524e4 334 BeaconCtx.NextBeaconRx = 0;
Shaun Nelson 38:182ba91524e4 335 BeaconCtx.BeaconTimingDelay = 0;
Shaun Nelson 38:182ba91524e4 336 }
Shaun Nelson 38:182ba91524e4 337 else
Shaun Nelson 38:182ba91524e4 338 {
Shaun Nelson 38:182ba91524e4 339 BeaconCtx.Ctrl.BeaconDelaySet = 0;
Shaun Nelson 38:182ba91524e4 340 BeaconCtx.Ctrl.AcquisitionPending = 0;
Shaun Nelson 38:182ba91524e4 341 BeaconCtx.Ctrl.AcquisitionTimerSet = 1;
Shaun Nelson 38:182ba91524e4 342 beaconEventTime = BeaconCtx.Cfg.DelayBeaconTimingAns;
Shaun Nelson 38:182ba91524e4 343
Shaun Nelson 38:182ba91524e4 344 rxBeaconSetup.SymbolTimeout = BeaconCtx.SymbolTimeout;
Shaun Nelson 38:182ba91524e4 345 rxBeaconSetup.RxTime = 0;
Shaun Nelson 38:182ba91524e4 346 rxBeaconSetup.DeviceAddress = *LoRaMacClassBParams.LoRaMacDevAddr;
Shaun Nelson 38:182ba91524e4 347 rxBeaconSetup.BeaconTimingChannel = BeaconCtx.BeaconTimingChannel;
Shaun Nelson 38:182ba91524e4 348 rxBeaconSetup.CustomFrequencyEnabled = BeaconCtx.Ctrl.CustomFreq;
Shaun Nelson 38:182ba91524e4 349 rxBeaconSetup.BeaconChannelSet = BeaconCtx.Ctrl.BeaconChannelSet;
Shaun Nelson 38:182ba91524e4 350 rxBeaconSetup.CustomFrequency = BeaconCtx.Frequency;
Shaun Nelson 38:182ba91524e4 351 rxBeaconSetup.BeaconTime = BeaconCtx.BeaconTime;
Shaun Nelson 38:182ba91524e4 352 rxBeaconSetup.BeaconInterval = BeaconCtx.Cfg.Interval;
Shaun Nelson 38:182ba91524e4 353
Shaun Nelson 38:182ba91524e4 354 RegionRxBeaconSetup( *LoRaMacClassBParams.LoRaMacRegion, &rxBeaconSetup, &LoRaMacClassBParams.McpsIndication->RxDatarate, &beaconChannelSet );
Shaun Nelson 38:182ba91524e4 355 BeaconCtx.Ctrl.BeaconChannelSet = beaconChannelSet;
Shaun Nelson 38:182ba91524e4 356 }
Shaun Nelson 38:182ba91524e4 357 }
Shaun Nelson 38:182ba91524e4 358 else
Shaun Nelson 38:182ba91524e4 359 {
Shaun Nelson 38:182ba91524e4 360 BeaconCtx.Ctrl.AcquisitionPending = 1;
Shaun Nelson 38:182ba91524e4 361 beaconEventTime = BeaconCtx.Cfg.Interval;
Shaun Nelson 38:182ba91524e4 362 if( BeaconCtx.Ctrl.AcquisitionTimerSet == 0 )
Shaun Nelson 38:182ba91524e4 363 {
Shaun Nelson 38:182ba91524e4 364 rxBeaconSetup.SymbolTimeout = BeaconCtx.SymbolTimeout;
Shaun Nelson 38:182ba91524e4 365 rxBeaconSetup.RxTime = 0;
Shaun Nelson 38:182ba91524e4 366 rxBeaconSetup.DeviceAddress = *LoRaMacClassBParams.LoRaMacDevAddr;
Shaun Nelson 38:182ba91524e4 367 rxBeaconSetup.BeaconTimingChannel = BeaconCtx.BeaconTimingChannel;
Shaun Nelson 38:182ba91524e4 368 rxBeaconSetup.CustomFrequencyEnabled = BeaconCtx.Ctrl.CustomFreq;
Shaun Nelson 38:182ba91524e4 369 rxBeaconSetup.BeaconChannelSet = BeaconCtx.Ctrl.BeaconChannelSet;
Shaun Nelson 38:182ba91524e4 370 rxBeaconSetup.CustomFrequency = BeaconCtx.Frequency;
Shaun Nelson 38:182ba91524e4 371 rxBeaconSetup.BeaconTime = BeaconCtx.BeaconTime;
Shaun Nelson 38:182ba91524e4 372 rxBeaconSetup.BeaconInterval = BeaconCtx.Cfg.Interval;
Shaun Nelson 38:182ba91524e4 373
Shaun Nelson 38:182ba91524e4 374 RegionRxBeaconSetup( *LoRaMacClassBParams.LoRaMacRegion, &rxBeaconSetup, &LoRaMacClassBParams.McpsIndication->RxDatarate, &beaconChannelSet );
Shaun Nelson 38:182ba91524e4 375 BeaconCtx.Ctrl.BeaconChannelSet = beaconChannelSet;
Shaun Nelson 38:182ba91524e4 376 }
Shaun Nelson 38:182ba91524e4 377 BeaconCtx.Ctrl.AcquisitionTimerSet = 0;
Shaun Nelson 38:182ba91524e4 378 }
Shaun Nelson 38:182ba91524e4 379 }
Shaun Nelson 38:182ba91524e4 380 break;
Shaun Nelson 38:182ba91524e4 381 }
Shaun Nelson 38:182ba91524e4 382 case BEACON_STATE_TIMEOUT:
Shaun Nelson 38:182ba91524e4 383 {
Shaun Nelson 38:182ba91524e4 384 // Store listen time
Shaun Nelson 38:182ba91524e4 385 BeaconCtx.ListenTime = currentTime - BeaconCtx.NextBeaconRx;
Shaun Nelson 38:182ba91524e4 386 // Setup next state
Shaun Nelson 38:182ba91524e4 387 BeaconState = BEACON_STATE_BEACON_MISSED;
Shaun Nelson 38:182ba91524e4 388 // no break here
Shaun Nelson 38:182ba91524e4 389 }
Shaun Nelson 38:182ba91524e4 390 case BEACON_STATE_BEACON_MISSED:
Shaun Nelson 38:182ba91524e4 391 {
Shaun Nelson 38:182ba91524e4 392 // We have to update the beacon time, since we missed a beacon
Shaun Nelson 38:182ba91524e4 393 BeaconCtx.BeaconTime += ( BeaconCtx.Cfg.Interval / 1000 );
Shaun Nelson 38:182ba91524e4 394
Shaun Nelson 38:182ba91524e4 395 // Update symbol timeout
Shaun Nelson 38:182ba91524e4 396 BeaconCtx.SymbolTimeout *= BeaconCtx.Cfg.SymbolToExpansionFactor;
Shaun Nelson 38:182ba91524e4 397 if( BeaconCtx.SymbolTimeout > BeaconCtx.Cfg.SymbolToExpansionMax )
Shaun Nelson 38:182ba91524e4 398 {
Shaun Nelson 38:182ba91524e4 399 BeaconCtx.SymbolTimeout = BeaconCtx.Cfg.SymbolToExpansionMax;
Shaun Nelson 38:182ba91524e4 400 }
Shaun Nelson 38:182ba91524e4 401 PingSlotCtx.SymbolTimeout *= PingSlotCtx.Cfg.SymbolToExpansionFactor;
Shaun Nelson 38:182ba91524e4 402 if( PingSlotCtx.SymbolTimeout > PingSlotCtx.Cfg.SymbolToExpansionMax )
Shaun Nelson 38:182ba91524e4 403 {
Shaun Nelson 38:182ba91524e4 404 PingSlotCtx.SymbolTimeout = PingSlotCtx.Cfg.SymbolToExpansionMax;
Shaun Nelson 38:182ba91524e4 405 }
Shaun Nelson 38:182ba91524e4 406 // Setup next state
Shaun Nelson 38:182ba91524e4 407 BeaconState = BEACON_STATE_REACQUISITION;
Shaun Nelson 38:182ba91524e4 408 // no break here
Shaun Nelson 38:182ba91524e4 409 }
Shaun Nelson 38:182ba91524e4 410 case BEACON_STATE_REACQUISITION:
Shaun Nelson 38:182ba91524e4 411 {
Shaun Nelson 38:182ba91524e4 412 if( ( currentTime - BeaconCtx.LastBeaconRx ) > BeaconCtx.Cfg.MaxBeaconLessPeriod )
Shaun Nelson 38:182ba91524e4 413 {
Shaun Nelson 38:182ba91524e4 414 activateTimer = true;
Shaun Nelson 38:182ba91524e4 415 BeaconState = BEACON_STATE_SWITCH_CLASS;
Shaun Nelson 38:182ba91524e4 416 }
Shaun Nelson 38:182ba91524e4 417 else
Shaun Nelson 38:182ba91524e4 418 {
Shaun Nelson 38:182ba91524e4 419 activateTimer = true;
Shaun Nelson 38:182ba91524e4 420 // Calculate the point in time of the next beacon
Shaun Nelson 38:182ba91524e4 421 beaconEventTime = ( ( currentTime - BeaconCtx.LastBeaconRx ) % BeaconCtx.Cfg.Interval );
Shaun Nelson 38:182ba91524e4 422 beaconEventTime = BeaconCtx.Cfg.Interval - beaconEventTime;
Shaun Nelson 38:182ba91524e4 423 // Take window enlargement into account
Shaun Nelson 38:182ba91524e4 424 beaconEventTime -= ( ( BeaconCtx.ListenTime * BeaconCtx.Cfg.SymbolToExpansionFactor ) >> 1 );
Shaun Nelson 38:182ba91524e4 425 beaconEventTime = TimerTempCompensation( beaconEventTime, BeaconCtx.Temperature );
Shaun Nelson 38:182ba91524e4 426 BeaconCtx.NextBeaconRx = currentTime + beaconEventTime;
Shaun Nelson 38:182ba91524e4 427
Shaun Nelson 38:182ba91524e4 428 // Make sure to transit to the correct state
Shaun Nelson 38:182ba91524e4 429 if( ( currentTime + BeaconCtx.Cfg.Guard ) < BeaconCtx.NextBeaconRx )
Shaun Nelson 38:182ba91524e4 430 {
Shaun Nelson 38:182ba91524e4 431 beaconEventTime -= BeaconCtx.Cfg.Guard;
Shaun Nelson 38:182ba91524e4 432 BeaconState = BEACON_STATE_IDLE;
Shaun Nelson 38:182ba91524e4 433 }
Shaun Nelson 38:182ba91524e4 434 else
Shaun Nelson 38:182ba91524e4 435 {
Shaun Nelson 38:182ba91524e4 436 BeaconState = BEACON_STATE_GUARD;
Shaun Nelson 38:182ba91524e4 437 }
Shaun Nelson 38:182ba91524e4 438
Shaun Nelson 38:182ba91524e4 439 if( PingSlotCtx.Ctrl.Assigned == 1 )
Shaun Nelson 38:182ba91524e4 440 {
Shaun Nelson 38:182ba91524e4 441 PingSlotState = PINGSLOT_STATE_CALC_PING_OFFSET;
Shaun Nelson 38:182ba91524e4 442 TimerSetValue( &PingSlotTimer, 1 );
Shaun Nelson 38:182ba91524e4 443 TimerStart( &PingSlotTimer );
Shaun Nelson 38:182ba91524e4 444
Shaun Nelson 38:182ba91524e4 445 MulticastSlotState = PINGSLOT_STATE_CALC_PING_OFFSET;
Shaun Nelson 38:182ba91524e4 446 TimerSetValue( &MulticastSlotTimer, 1 );
Shaun Nelson 38:182ba91524e4 447 TimerStart( &MulticastSlotTimer );
Shaun Nelson 38:182ba91524e4 448 }
Shaun Nelson 38:182ba91524e4 449 }
Shaun Nelson 38:182ba91524e4 450 BeaconCtx.Ctrl.BeaconAcquired = 0;
Shaun Nelson 38:182ba91524e4 451
Shaun Nelson 38:182ba91524e4 452 if( BeaconCtx.Ctrl.ResumeBeaconing == 0 )
Shaun Nelson 38:182ba91524e4 453 {
Shaun Nelson 38:182ba91524e4 454 LoRaMacClassBParams.MlmeIndication->MlmeIndication = MLME_BEACON;
Shaun Nelson 38:182ba91524e4 455 LoRaMacClassBParams.MlmeIndication->Status = LORAMAC_EVENT_INFO_STATUS_BEACON_LOST;
Shaun Nelson 38:182ba91524e4 456 LoRaMacClassBParams.LoRaMacFlags->Bits.MlmeInd = 1;
Shaun Nelson 38:182ba91524e4 457
Shaun Nelson 38:182ba91524e4 458 TimerSetValue( LoRaMacClassBParams.MacStateCheckTimer, 1 );
Shaun Nelson 38:182ba91524e4 459 TimerStart( LoRaMacClassBParams.MacStateCheckTimer );
Shaun Nelson 38:182ba91524e4 460 LoRaMacClassBParams.LoRaMacFlags->Bits.MacDone = 1;
Shaun Nelson 38:182ba91524e4 461 }
Shaun Nelson 38:182ba91524e4 462 BeaconCtx.Ctrl.ResumeBeaconing = 0;
Shaun Nelson 38:182ba91524e4 463 break;
Shaun Nelson 38:182ba91524e4 464 }
Shaun Nelson 38:182ba91524e4 465 case BEACON_STATE_LOCKED:
Shaun Nelson 38:182ba91524e4 466 {
Shaun Nelson 38:182ba91524e4 467 activateTimer = true;
Shaun Nelson 38:182ba91524e4 468 // Calculate the point in time of the next beacon
Shaun Nelson 38:182ba91524e4 469 beaconEventTime = ( ( currentTime - BeaconCtx.LastBeaconRx ) % BeaconCtx.Cfg.Interval );
Shaun Nelson 38:182ba91524e4 470 beaconEventTime = BeaconCtx.Cfg.Interval - beaconEventTime;
Shaun Nelson 38:182ba91524e4 471 beaconEventTime = TimerTempCompensation( beaconEventTime, BeaconCtx.Temperature );
Shaun Nelson 38:182ba91524e4 472 BeaconCtx.NextBeaconRx = currentTime + beaconEventTime;
Shaun Nelson 38:182ba91524e4 473
Shaun Nelson 38:182ba91524e4 474 // Make sure to transit to the correct state
Shaun Nelson 38:182ba91524e4 475 if( ( currentTime + BeaconCtx.Cfg.Guard ) < BeaconCtx.NextBeaconRx )
Shaun Nelson 38:182ba91524e4 476 {
Shaun Nelson 38:182ba91524e4 477 beaconEventTime -= BeaconCtx.Cfg.Guard;
Shaun Nelson 38:182ba91524e4 478 BeaconState = BEACON_STATE_IDLE;
Shaun Nelson 38:182ba91524e4 479 }
Shaun Nelson 38:182ba91524e4 480 else
Shaun Nelson 38:182ba91524e4 481 {
Shaun Nelson 38:182ba91524e4 482 BeaconState = BEACON_STATE_GUARD;
Shaun Nelson 38:182ba91524e4 483 }
Shaun Nelson 38:182ba91524e4 484
Shaun Nelson 38:182ba91524e4 485 if( LoRaMacClassBParams.LoRaMacFlags->Bits.MlmeReq == 1 )
Shaun Nelson 38:182ba91524e4 486 {
Shaun Nelson 38:182ba91524e4 487 // index = GetMlmeConfirmIndex( MlmeConfirmQueue, MLME_BEACON_ACQUISITION, MlmeConfirmQueueCnt );
Shaun Nelson 38:182ba91524e4 488 index = LoRaMacClassBCallbacks.GetMlmeConfrimIndex( LoRaMacClassBParams.MlmeConfirmQueue, MLME_BEACON_ACQUISITION );
Shaun Nelson 38:182ba91524e4 489 if( index < LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
Shaun Nelson 38:182ba91524e4 490 {
Shaun Nelson 38:182ba91524e4 491 LoRaMacClassBParams.MlmeConfirmQueue[index].Status = LORAMAC_EVENT_INFO_STATUS_OK;
Shaun Nelson 38:182ba91524e4 492 LoRaMacClassBParams.MlmeConfirm->TxTimeOnAir = 0;
Shaun Nelson 38:182ba91524e4 493 }
Shaun Nelson 38:182ba91524e4 494 }
Shaun Nelson 38:182ba91524e4 495
Shaun Nelson 38:182ba91524e4 496 if( PingSlotCtx.Ctrl.Assigned == 1 )
Shaun Nelson 38:182ba91524e4 497 {
Shaun Nelson 38:182ba91524e4 498 PingSlotState = PINGSLOT_STATE_CALC_PING_OFFSET;
Shaun Nelson 38:182ba91524e4 499 TimerSetValue( &PingSlotTimer, 1 );
Shaun Nelson 38:182ba91524e4 500 TimerStart( &PingSlotTimer );
Shaun Nelson 38:182ba91524e4 501
Shaun Nelson 38:182ba91524e4 502 MulticastSlotState = PINGSLOT_STATE_CALC_PING_OFFSET;
Shaun Nelson 38:182ba91524e4 503 TimerSetValue( &MulticastSlotTimer, 1 );
Shaun Nelson 38:182ba91524e4 504 TimerStart( &MulticastSlotTimer );
Shaun Nelson 38:182ba91524e4 505 }
Shaun Nelson 38:182ba91524e4 506 BeaconCtx.Ctrl.AcquisitionPending = 0;
Shaun Nelson 38:182ba91524e4 507
Shaun Nelson 38:182ba91524e4 508 if( BeaconCtx.Ctrl.ResumeBeaconing == 0 )
Shaun Nelson 38:182ba91524e4 509 {
Shaun Nelson 38:182ba91524e4 510 LoRaMacClassBParams.MlmeIndication->MlmeIndication = MLME_BEACON;
Shaun Nelson 38:182ba91524e4 511 LoRaMacClassBParams.MlmeIndication->Status = LORAMAC_EVENT_INFO_STATUS_BEACON_LOCKED;
Shaun Nelson 38:182ba91524e4 512 LoRaMacClassBParams.LoRaMacFlags->Bits.MlmeInd = 1;
Shaun Nelson 38:182ba91524e4 513
Shaun Nelson 38:182ba91524e4 514 TimerSetValue( LoRaMacClassBParams.MacStateCheckTimer, 1 );
Shaun Nelson 38:182ba91524e4 515 TimerStart( LoRaMacClassBParams.MacStateCheckTimer );
Shaun Nelson 38:182ba91524e4 516 LoRaMacClassBParams.LoRaMacFlags->Bits.MacDone = 1;
Shaun Nelson 38:182ba91524e4 517 }
Shaun Nelson 38:182ba91524e4 518 BeaconCtx.Ctrl.ResumeBeaconing = 0;
Shaun Nelson 38:182ba91524e4 519 break;
Shaun Nelson 38:182ba91524e4 520 }
Shaun Nelson 38:182ba91524e4 521 case BEACON_STATE_IDLE:
Shaun Nelson 38:182ba91524e4 522 {
Shaun Nelson 38:182ba91524e4 523 activateTimer = true;
Shaun Nelson 38:182ba91524e4 524 GetTemperatureLevel( &LoRaMacClassBCallbacks, &BeaconCtx );
Shaun Nelson 38:182ba91524e4 525 beaconEventTime = BeaconCtx.NextBeaconRx - RADIO_WAKEUP_TIME;
Shaun Nelson 38:182ba91524e4 526 currentTime = TimerGetCurrentTime( );
Shaun Nelson 38:182ba91524e4 527
Shaun Nelson 38:182ba91524e4 528 if( beaconEventTime > currentTime )
Shaun Nelson 38:182ba91524e4 529 {
Shaun Nelson 38:182ba91524e4 530 BeaconState = BEACON_STATE_GUARD;
Shaun Nelson 38:182ba91524e4 531 beaconEventTime -= currentTime;
Shaun Nelson 38:182ba91524e4 532 beaconEventTime = TimerTempCompensation( beaconEventTime, BeaconCtx.Temperature );
Shaun Nelson 38:182ba91524e4 533 }
Shaun Nelson 38:182ba91524e4 534 else
Shaun Nelson 38:182ba91524e4 535 {
Shaun Nelson 38:182ba91524e4 536 BeaconState = BEACON_STATE_REACQUISITION;
Shaun Nelson 38:182ba91524e4 537 beaconEventTime = 1;
Shaun Nelson 38:182ba91524e4 538 }
Shaun Nelson 38:182ba91524e4 539 break;
Shaun Nelson 38:182ba91524e4 540 }
Shaun Nelson 38:182ba91524e4 541 case BEACON_STATE_GUARD:
Shaun Nelson 38:182ba91524e4 542 {
Shaun Nelson 38:182ba91524e4 543 BeaconState = BEACON_STATE_RX;
Shaun Nelson 38:182ba91524e4 544
Shaun Nelson 38:182ba91524e4 545 rxBeaconSetup.SymbolTimeout = BeaconCtx.SymbolTimeout;
Shaun Nelson 38:182ba91524e4 546 rxBeaconSetup.RxTime = BeaconCtx.Cfg.Reserved;
Shaun Nelson 38:182ba91524e4 547 rxBeaconSetup.DeviceAddress = *LoRaMacClassBParams.LoRaMacDevAddr;
Shaun Nelson 38:182ba91524e4 548 rxBeaconSetup.BeaconTimingChannel = BeaconCtx.BeaconTimingChannel;
Shaun Nelson 38:182ba91524e4 549 rxBeaconSetup.CustomFrequencyEnabled = BeaconCtx.Ctrl.CustomFreq;
Shaun Nelson 38:182ba91524e4 550 rxBeaconSetup.BeaconChannelSet = BeaconCtx.Ctrl.BeaconChannelSet;
Shaun Nelson 38:182ba91524e4 551 rxBeaconSetup.CustomFrequency = BeaconCtx.Frequency;
Shaun Nelson 38:182ba91524e4 552 rxBeaconSetup.BeaconTime = BeaconCtx.BeaconTime;
Shaun Nelson 38:182ba91524e4 553 rxBeaconSetup.BeaconInterval = BeaconCtx.Cfg.Interval;
Shaun Nelson 38:182ba91524e4 554
Shaun Nelson 38:182ba91524e4 555 RegionRxBeaconSetup( *LoRaMacClassBParams.LoRaMacRegion, &rxBeaconSetup, &LoRaMacClassBParams.McpsIndication->RxDatarate, &beaconChannelSet );
Shaun Nelson 38:182ba91524e4 556 BeaconCtx.Ctrl.BeaconChannelSet = beaconChannelSet;
Shaun Nelson 38:182ba91524e4 557 break;
Shaun Nelson 38:182ba91524e4 558 }
Shaun Nelson 38:182ba91524e4 559 case BEACON_STATE_SWITCH_CLASS:
Shaun Nelson 38:182ba91524e4 560 {
Shaun Nelson 38:182ba91524e4 561 if( LoRaMacClassBParams.LoRaMacFlags->Bits.MlmeReq == 1 )
Shaun Nelson 38:182ba91524e4 562 {
Shaun Nelson 38:182ba91524e4 563 // index = GetMlmeConfirmIndex( MlmeConfirmQueue, MLME_BEACON_ACQUISITION, MlmeConfirmQueueCnt );
Shaun Nelson 38:182ba91524e4 564 index = LoRaMacClassBCallbacks.GetMlmeConfrimIndex( LoRaMacClassBParams.MlmeConfirmQueue, MLME_BEACON_ACQUISITION );
Shaun Nelson 38:182ba91524e4 565 if( index < LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
Shaun Nelson 38:182ba91524e4 566 {
Shaun Nelson 38:182ba91524e4 567 LoRaMacClassBParams.MlmeConfirmQueue[index].Status = LORAMAC_EVENT_INFO_STATUS_BEACON_NOT_FOUND;
Shaun Nelson 38:182ba91524e4 568 }
Shaun Nelson 38:182ba91524e4 569 }
Shaun Nelson 38:182ba91524e4 570 else
Shaun Nelson 38:182ba91524e4 571 {
Shaun Nelson 38:182ba91524e4 572 LoRaMacClassBParams.MlmeIndication->MlmeIndication = MLME_SWITCH_CLASS;
Shaun Nelson 38:182ba91524e4 573 LoRaMacClassBParams.MlmeIndication->Status = LORAMAC_EVENT_INFO_STATUS_OK;
Shaun Nelson 38:182ba91524e4 574 PingSlotCtx.Ctrl.Assigned = 0;
Shaun Nelson 38:182ba91524e4 575 LoRaMacClassBParams.LoRaMacFlags->Bits.MlmeInd = 1;
Shaun Nelson 38:182ba91524e4 576 }
Shaun Nelson 38:182ba91524e4 577 BeaconState = BEACON_STATE_ACQUISITION;
Shaun Nelson 38:182ba91524e4 578
Shaun Nelson 38:182ba91524e4 579 BeaconCtx.Ctrl.BeaconMode = 0;
Shaun Nelson 38:182ba91524e4 580 BeaconCtx.Ctrl.AcquisitionPending = 0;
Shaun Nelson 38:182ba91524e4 581 BeaconCtx.Ctrl.AcquisitionTimerSet = 0;
Shaun Nelson 38:182ba91524e4 582 LoRaMacClassBParams.LoRaMacFlags->Bits.MacDone = 1;
Shaun Nelson 38:182ba91524e4 583
Shaun Nelson 38:182ba91524e4 584 TimerSetValue( LoRaMacClassBParams.MacStateCheckTimer, beaconEventTime );
Shaun Nelson 38:182ba91524e4 585 TimerStart( LoRaMacClassBParams.MacStateCheckTimer );
Shaun Nelson 38:182ba91524e4 586 break;
Shaun Nelson 38:182ba91524e4 587 }
Shaun Nelson 38:182ba91524e4 588 default:
Shaun Nelson 38:182ba91524e4 589 {
Shaun Nelson 38:182ba91524e4 590 BeaconState = BEACON_STATE_ACQUISITION;
Shaun Nelson 38:182ba91524e4 591 break;
Shaun Nelson 38:182ba91524e4 592 }
Shaun Nelson 38:182ba91524e4 593 }
Shaun Nelson 38:182ba91524e4 594
Shaun Nelson 38:182ba91524e4 595 if( activateTimer == true )
Shaun Nelson 38:182ba91524e4 596 {
Shaun Nelson 40:f7ce84dc9363 597 BeaconEventTime = beaconEventTime;
Shaun Nelson 40:f7ce84dc9363 598
Shaun Nelson 38:182ba91524e4 599 TimerSetValue( &BeaconTimer, beaconEventTime );
Shaun Nelson 38:182ba91524e4 600 TimerStart( &BeaconTimer );
Shaun Nelson 38:182ba91524e4 601 }
Shaun Nelson 40:f7ce84dc9363 602 else
Shaun Nelson 40:f7ce84dc9363 603 BeaconEventTime = 0;
Shaun Nelson 40:f7ce84dc9363 604
Shaun Nelson 38:182ba91524e4 605 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 606 }
Shaun Nelson 38:182ba91524e4 607
Shaun Nelson 38:182ba91524e4 608 void LoRaMacClassBPingSlotTimerEvent( void )
Shaun Nelson 38:182ba91524e4 609 {
Shaun Nelson 38:182ba91524e4 610 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 611 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 612 PhyParam_t phyParam;
Shaun Nelson 38:182ba91524e4 613 RxConfigParams_t pingSlotRxConfig;
Shaun Nelson 38:182ba91524e4 614 TimerTime_t pingSlotTime = 0;
Shaun Nelson 38:182ba91524e4 615
Shaun Nelson 38:182ba91524e4 616 TimerStop( &PingSlotTimer );
Shaun Nelson 38:182ba91524e4 617
Shaun Nelson 38:182ba91524e4 618 switch( PingSlotState )
Shaun Nelson 38:182ba91524e4 619 {
Shaun Nelson 38:182ba91524e4 620 case PINGSLOT_STATE_CALC_PING_OFFSET:
Shaun Nelson 38:182ba91524e4 621 {
Shaun Nelson 38:182ba91524e4 622 LoRaMacBeaconComputePingOffset( BeaconCtx.BeaconTime,
Shaun Nelson 38:182ba91524e4 623 *LoRaMacClassBParams.LoRaMacDevAddr,
Shaun Nelson 38:182ba91524e4 624 PingSlotCtx.PingPeriod,
Shaun Nelson 38:182ba91524e4 625 &( PingSlotCtx.PingOffset ) );
Shaun Nelson 38:182ba91524e4 626 PingSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 627 // no break
Shaun Nelson 38:182ba91524e4 628 }
Shaun Nelson 38:182ba91524e4 629 case PINGSLOT_STATE_SET_TIMER:
Shaun Nelson 38:182ba91524e4 630 {
Shaun Nelson 38:182ba91524e4 631 if( CalcNextSlotTime( PingSlotCtx.PingOffset, PingSlotCtx.PingPeriod, &pingSlotTime ) == true )
Shaun Nelson 38:182ba91524e4 632 {
Shaun Nelson 38:182ba91524e4 633 // Start the timer if the ping slot time is in range
Shaun Nelson 38:182ba91524e4 634 PingSlotState = PINGSLOT_STATE_IDLE;
Shaun Nelson 38:182ba91524e4 635 TimerSetValue( &PingSlotTimer, pingSlotTime );
Shaun Nelson 38:182ba91524e4 636 TimerStart( &PingSlotTimer );
Shaun Nelson 38:182ba91524e4 637 }
Shaun Nelson 38:182ba91524e4 638 break;
Shaun Nelson 38:182ba91524e4 639 }
Shaun Nelson 38:182ba91524e4 640 case PINGSLOT_STATE_IDLE:
Shaun Nelson 38:182ba91524e4 641 {
Shaun Nelson 38:182ba91524e4 642 uint32_t frequency = PingSlotCtx.Frequency;
Shaun Nelson 38:182ba91524e4 643
Shaun Nelson 38:182ba91524e4 644 if( PingSlotCtx.Ctrl.CustomFreq == 0 )
Shaun Nelson 38:182ba91524e4 645 {
Shaun Nelson 38:182ba91524e4 646 // Restore floor plan
Shaun Nelson 38:182ba91524e4 647 getPhy.Attribute = PHY_PINGSLOT_CHANNEL_FREQ;
Shaun Nelson 38:182ba91524e4 648 getPhy.DeviceAddress = *LoRaMacClassBParams.LoRaMacDevAddr;
Shaun Nelson 38:182ba91524e4 649 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 650 frequency = phyParam.Value;
Shaun Nelson 38:182ba91524e4 651 }
Shaun Nelson 38:182ba91524e4 652
Shaun Nelson 38:182ba91524e4 653 if( MulticastSlotState != PINGSLOT_STATE_RX )
Shaun Nelson 38:182ba91524e4 654 {
Shaun Nelson 38:182ba91524e4 655 if( BeaconCtx.Ctrl.BeaconAcquired == 1 )
Shaun Nelson 38:182ba91524e4 656 {
Shaun Nelson 38:182ba91524e4 657 RegionComputeRxWindowParameters( *LoRaMacClassBParams.LoRaMacRegion,
Shaun Nelson 38:182ba91524e4 658 PingSlotCtx.Datarate,
Shaun Nelson 38:182ba91524e4 659 LoRaMacClassBParams.LoRaMacParams->MinRxSymbols,
Shaun Nelson 38:182ba91524e4 660 LoRaMacClassBParams.LoRaMacParams->SystemMaxRxError,
Shaun Nelson 38:182ba91524e4 661 &pingSlotRxConfig );
Shaun Nelson 38:182ba91524e4 662 PingSlotCtx.SymbolTimeout = pingSlotRxConfig.WindowTimeout;
Shaun Nelson 38:182ba91524e4 663 }
Shaun Nelson 38:182ba91524e4 664 PingSlotState = PINGSLOT_STATE_RX;
Shaun Nelson 38:182ba91524e4 665
Shaun Nelson 38:182ba91524e4 666 pingSlotRxConfig.Datarate = PingSlotCtx.Datarate;
Shaun Nelson 38:182ba91524e4 667 pingSlotRxConfig.DownlinkDwellTime = LoRaMacClassBParams.LoRaMacParams->DownlinkDwellTime;
Shaun Nelson 38:182ba91524e4 668 pingSlotRxConfig.RepeaterSupport = LoRaMacClassBParams.LoRaMacParams->RepeaterSupport;
Shaun Nelson 38:182ba91524e4 669 pingSlotRxConfig.Frequency = frequency;
Shaun Nelson 38:182ba91524e4 670 pingSlotRxConfig.RxContinuous = false;
Shaun Nelson 38:182ba91524e4 671 pingSlotRxConfig.Window = 1;
Shaun Nelson 38:182ba91524e4 672
Shaun Nelson 38:182ba91524e4 673 RegionRxConfig( *LoRaMacClassBParams.LoRaMacRegion, &pingSlotRxConfig, ( int8_t* )&LoRaMacClassBParams.McpsIndication->RxDatarate );
Shaun Nelson 38:182ba91524e4 674
Shaun Nelson 38:182ba91524e4 675 if( pingSlotRxConfig.RxContinuous == false )
Shaun Nelson 38:182ba91524e4 676 {
Shaun Nelson 38:182ba91524e4 677 Radio.Rx( LoRaMacClassBParams.LoRaMacParams->MaxRxWindow );
Shaun Nelson 38:182ba91524e4 678 }
Shaun Nelson 38:182ba91524e4 679 else
Shaun Nelson 38:182ba91524e4 680 {
Shaun Nelson 38:182ba91524e4 681 Radio.Rx( 0 ); // Continuous mode
Shaun Nelson 38:182ba91524e4 682 }
Shaun Nelson 38:182ba91524e4 683 }
Shaun Nelson 38:182ba91524e4 684 else
Shaun Nelson 38:182ba91524e4 685 {
Shaun Nelson 38:182ba91524e4 686 // Multicast slots have priority. Skip Rx
Shaun Nelson 38:182ba91524e4 687 PingSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 688 TimerSetValue( &PingSlotTimer, PingSlotCtx.Cfg.PingSlotWindow );
Shaun Nelson 38:182ba91524e4 689 TimerStart( &PingSlotTimer );
Shaun Nelson 38:182ba91524e4 690 }
Shaun Nelson 38:182ba91524e4 691 break;
Shaun Nelson 38:182ba91524e4 692 }
Shaun Nelson 38:182ba91524e4 693 default:
Shaun Nelson 38:182ba91524e4 694 {
Shaun Nelson 38:182ba91524e4 695 PingSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 696 break;
Shaun Nelson 38:182ba91524e4 697 }
Shaun Nelson 38:182ba91524e4 698 }
Shaun Nelson 38:182ba91524e4 699 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 700 }
Shaun Nelson 38:182ba91524e4 701
Shaun Nelson 38:182ba91524e4 702 void LoRaMacClassBMulticastSlotTimerEvent( void )
Shaun Nelson 38:182ba91524e4 703 {
Shaun Nelson 38:182ba91524e4 704 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 705 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 706 PhyParam_t phyParam;
Shaun Nelson 38:182ba91524e4 707 RxConfigParams_t multicastSlotRxConfig;
Shaun Nelson 38:182ba91524e4 708 TimerTime_t multicastSlotTime = 0;
Shaun Nelson 38:182ba91524e4 709 TimerTime_t slotTime = 0;
Shaun Nelson 38:182ba91524e4 710 MulticastParams_t *cur = LoRaMacClassBParams.MulticastChannels;
Shaun Nelson 38:182ba91524e4 711
Shaun Nelson 38:182ba91524e4 712 TimerStop( &MulticastSlotTimer );
Shaun Nelson 38:182ba91524e4 713
Shaun Nelson 38:182ba91524e4 714 if( cur == NULL )
Shaun Nelson 38:182ba91524e4 715 {
Shaun Nelson 38:182ba91524e4 716 return;
Shaun Nelson 38:182ba91524e4 717 }
Shaun Nelson 38:182ba91524e4 718
Shaun Nelson 38:182ba91524e4 719 switch( MulticastSlotState )
Shaun Nelson 38:182ba91524e4 720 {
Shaun Nelson 38:182ba91524e4 721 case PINGSLOT_STATE_CALC_PING_OFFSET:
Shaun Nelson 38:182ba91524e4 722 {
Shaun Nelson 38:182ba91524e4 723 while( cur != NULL )
Shaun Nelson 38:182ba91524e4 724 {
Shaun Nelson 38:182ba91524e4 725 LoRaMacBeaconComputePingOffset( BeaconCtx.BeaconTime,
Shaun Nelson 38:182ba91524e4 726 cur->Address,
Shaun Nelson 38:182ba91524e4 727 PingSlotCtx.PingPeriod,
Shaun Nelson 38:182ba91524e4 728 &( cur->PingOffset ) );
Shaun Nelson 38:182ba91524e4 729 cur = cur->Next;
Shaun Nelson 38:182ba91524e4 730 }
Shaun Nelson 38:182ba91524e4 731 MulticastSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 732 // no break
Shaun Nelson 38:182ba91524e4 733 }
Shaun Nelson 38:182ba91524e4 734 case PINGSLOT_STATE_SET_TIMER:
Shaun Nelson 38:182ba91524e4 735 {
Shaun Nelson 38:182ba91524e4 736 cur = LoRaMacClassBParams.MulticastChannels;
Shaun Nelson 38:182ba91524e4 737 PingSlotCtx.NextMulticastChannel = NULL;
Shaun Nelson 38:182ba91524e4 738
Shaun Nelson 38:182ba91524e4 739 while( cur != NULL )
Shaun Nelson 38:182ba91524e4 740 {
Shaun Nelson 38:182ba91524e4 741 if( CalcNextSlotTime( cur->PingOffset, PingSlotCtx.PingPeriod, &slotTime ) == true )
Shaun Nelson 38:182ba91524e4 742 {
Shaun Nelson 38:182ba91524e4 743 if( ( multicastSlotTime == 0 ) || ( multicastSlotTime > slotTime ) )
Shaun Nelson 38:182ba91524e4 744 {
Shaun Nelson 38:182ba91524e4 745 // Update the slot time and the next multicast channel
Shaun Nelson 38:182ba91524e4 746 multicastSlotTime = slotTime;
Shaun Nelson 38:182ba91524e4 747 PingSlotCtx.NextMulticastChannel = cur;
Shaun Nelson 38:182ba91524e4 748 }
Shaun Nelson 38:182ba91524e4 749 }
Shaun Nelson 38:182ba91524e4 750 cur = cur->Next;
Shaun Nelson 38:182ba91524e4 751 }
Shaun Nelson 38:182ba91524e4 752
Shaun Nelson 38:182ba91524e4 753 if( PingSlotCtx.NextMulticastChannel != NULL )
Shaun Nelson 38:182ba91524e4 754 {
Shaun Nelson 38:182ba91524e4 755 // Start the timer if the ping slot time is in range
Shaun Nelson 38:182ba91524e4 756 MulticastSlotState = PINGSLOT_STATE_IDLE;
Shaun Nelson 38:182ba91524e4 757 TimerSetValue( &MulticastSlotTimer, multicastSlotTime );
Shaun Nelson 38:182ba91524e4 758 TimerStart( &MulticastSlotTimer );
Shaun Nelson 38:182ba91524e4 759 }
Shaun Nelson 38:182ba91524e4 760 break;
Shaun Nelson 38:182ba91524e4 761 }
Shaun Nelson 38:182ba91524e4 762 case PINGSLOT_STATE_IDLE:
Shaun Nelson 38:182ba91524e4 763 {
Shaun Nelson 38:182ba91524e4 764 uint32_t frequency = PingSlotCtx.Frequency;
Shaun Nelson 38:182ba91524e4 765
Shaun Nelson 38:182ba91524e4 766 if( PingSlotCtx.NextMulticastChannel == NULL )
Shaun Nelson 38:182ba91524e4 767 {
Shaun Nelson 38:182ba91524e4 768 MulticastSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 769 TimerSetValue( &MulticastSlotTimer, 1 );
Shaun Nelson 38:182ba91524e4 770 TimerStart( &MulticastSlotTimer );
Shaun Nelson 38:182ba91524e4 771 break;
Shaun Nelson 38:182ba91524e4 772 }
Shaun Nelson 38:182ba91524e4 773
Shaun Nelson 38:182ba91524e4 774 if( PingSlotCtx.Ctrl.CustomFreq == 0 )
Shaun Nelson 38:182ba91524e4 775 {
Shaun Nelson 38:182ba91524e4 776 // Restore floor plan
Shaun Nelson 38:182ba91524e4 777 getPhy.Attribute = PHY_PINGSLOT_CHANNEL_FREQ;
Shaun Nelson 38:182ba91524e4 778 getPhy.DeviceAddress = PingSlotCtx.NextMulticastChannel->Address;
Shaun Nelson 38:182ba91524e4 779 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 780 frequency = phyParam.Value;
Shaun Nelson 38:182ba91524e4 781 }
Shaun Nelson 38:182ba91524e4 782
Shaun Nelson 38:182ba91524e4 783 if( BeaconCtx.Ctrl.BeaconAcquired == 1 )
Shaun Nelson 38:182ba91524e4 784 {
Shaun Nelson 38:182ba91524e4 785 RegionComputeRxWindowParameters( *LoRaMacClassBParams.LoRaMacRegion,
Shaun Nelson 38:182ba91524e4 786 PingSlotCtx.Datarate,
Shaun Nelson 38:182ba91524e4 787 LoRaMacClassBParams.LoRaMacParams->MinRxSymbols,
Shaun Nelson 38:182ba91524e4 788 LoRaMacClassBParams.LoRaMacParams->SystemMaxRxError,
Shaun Nelson 38:182ba91524e4 789 &multicastSlotRxConfig );
Shaun Nelson 38:182ba91524e4 790 PingSlotCtx.SymbolTimeout = multicastSlotRxConfig.WindowTimeout;
Shaun Nelson 38:182ba91524e4 791 }
Shaun Nelson 38:182ba91524e4 792 MulticastSlotState = PINGSLOT_STATE_RX;
Shaun Nelson 38:182ba91524e4 793
Shaun Nelson 38:182ba91524e4 794 multicastSlotRxConfig.Datarate = PingSlotCtx.Datarate;
Shaun Nelson 38:182ba91524e4 795 multicastSlotRxConfig.DownlinkDwellTime = LoRaMacClassBParams.LoRaMacParams->DownlinkDwellTime;
Shaun Nelson 38:182ba91524e4 796 multicastSlotRxConfig.RepeaterSupport = LoRaMacClassBParams.LoRaMacParams->RepeaterSupport;
Shaun Nelson 38:182ba91524e4 797 multicastSlotRxConfig.Frequency = frequency;
Shaun Nelson 38:182ba91524e4 798 multicastSlotRxConfig.RxContinuous = false;
Shaun Nelson 38:182ba91524e4 799 multicastSlotRxConfig.Window = 1;
Shaun Nelson 38:182ba91524e4 800
Shaun Nelson 38:182ba91524e4 801 RegionRxConfig( *LoRaMacClassBParams.LoRaMacRegion, &multicastSlotRxConfig, ( int8_t* )&LoRaMacClassBParams.McpsIndication->RxDatarate );
Shaun Nelson 38:182ba91524e4 802
Shaun Nelson 38:182ba91524e4 803 if( multicastSlotRxConfig.RxContinuous == false )
Shaun Nelson 38:182ba91524e4 804 {
Shaun Nelson 38:182ba91524e4 805 Radio.Rx( LoRaMacClassBParams.LoRaMacParams->MaxRxWindow );
Shaun Nelson 38:182ba91524e4 806 }
Shaun Nelson 38:182ba91524e4 807 else
Shaun Nelson 38:182ba91524e4 808 {
Shaun Nelson 38:182ba91524e4 809 Radio.Rx( 0 ); // Continuous mode
Shaun Nelson 38:182ba91524e4 810 }
Shaun Nelson 38:182ba91524e4 811 break;
Shaun Nelson 38:182ba91524e4 812 }
Shaun Nelson 38:182ba91524e4 813 default:
Shaun Nelson 38:182ba91524e4 814 {
Shaun Nelson 38:182ba91524e4 815 MulticastSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 816 break;
Shaun Nelson 38:182ba91524e4 817 }
Shaun Nelson 38:182ba91524e4 818 }
Shaun Nelson 38:182ba91524e4 819 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 820 }
Shaun Nelson 38:182ba91524e4 821
Shaun Nelson 38:182ba91524e4 822 bool LoRaMacClassBRxBeacon( uint8_t *payload, uint16_t size )
Shaun Nelson 38:182ba91524e4 823 {
Shaun Nelson 38:182ba91524e4 824 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 825 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 826 PhyParam_t phyParam;
Shaun Nelson 38:182ba91524e4 827 bool beaconReceived = false;
Shaun Nelson 38:182ba91524e4 828 uint16_t crc0 = 0;
Shaun Nelson 38:182ba91524e4 829 uint16_t crc1 = 0;
Shaun Nelson 38:182ba91524e4 830 uint16_t beaconCrc0 = 0;
Shaun Nelson 38:182ba91524e4 831 uint16_t beaconCrc1 = 0;
Shaun Nelson 38:182ba91524e4 832 uint8_t rfuOffset1 = 0;
Shaun Nelson 38:182ba91524e4 833 uint8_t rfuOffset2 = 0;
Shaun Nelson 38:182ba91524e4 834
Shaun Nelson 38:182ba91524e4 835 getPhy.Attribute = PHY_BEACON_SIZE;
Shaun Nelson 38:182ba91524e4 836 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 837
Shaun Nelson 38:182ba91524e4 838 // For beacon payload sizes > 17 we need to apply an offset
Shaun Nelson 38:182ba91524e4 839 if( phyParam.Value > 17 )
Shaun Nelson 38:182ba91524e4 840 {
Shaun Nelson 38:182ba91524e4 841 rfuOffset1 = 1;
Shaun Nelson 38:182ba91524e4 842 rfuOffset2 = 1;
Shaun Nelson 38:182ba91524e4 843 }
Shaun Nelson 38:182ba91524e4 844
Shaun Nelson 38:182ba91524e4 845 // Verify if we are in the state where we expect a beacon
Shaun Nelson 38:182ba91524e4 846 if( ( BeaconState == BEACON_STATE_RX ) || ( BeaconCtx.Ctrl.AcquisitionPending == 1 ) )
Shaun Nelson 38:182ba91524e4 847 {
Shaun Nelson 38:182ba91524e4 848 if( size == phyParam.Value )
Shaun Nelson 38:182ba91524e4 849 {
Shaun Nelson 38:182ba91524e4 850 beaconCrc0 = ( ( uint16_t ) payload[6 + rfuOffset1] ) & 0x00FF;
Shaun Nelson 38:182ba91524e4 851 beaconCrc0 |= ( ( uint16_t ) payload[7 + rfuOffset1] << 8 ) & 0xFF00;
Shaun Nelson 38:182ba91524e4 852 crc0 = BeaconCrc( payload, 6 + rfuOffset1 );
Shaun Nelson 38:182ba91524e4 853
Shaun Nelson 38:182ba91524e4 854 // Validate the first crc of the beacon frame
Shaun Nelson 38:182ba91524e4 855 if( crc0 == beaconCrc0 )
Shaun Nelson 38:182ba91524e4 856 {
Shaun Nelson 38:182ba91524e4 857 BeaconCtx.BeaconTime = ( ( uint32_t ) payload[2 + rfuOffset1] ) & 0x000000FF;
Shaun Nelson 38:182ba91524e4 858 BeaconCtx.BeaconTime |= ( ( uint32_t ) ( payload[3 + rfuOffset1] << 8 ) ) & 0x0000FF00;
Shaun Nelson 38:182ba91524e4 859 BeaconCtx.BeaconTime |= ( ( uint32_t ) ( payload[4 + rfuOffset1] << 16 ) ) & 0x00FF0000;
Shaun Nelson 38:182ba91524e4 860 BeaconCtx.BeaconTime |= ( ( uint32_t ) ( payload[5 + rfuOffset1] << 24 ) ) & 0xFF000000;
Shaun Nelson 38:182ba91524e4 861 LoRaMacClassBParams.MlmeIndication->BeaconInfo.Time = BeaconCtx.BeaconTime;
Shaun Nelson 38:182ba91524e4 862 beaconReceived = true;
Shaun Nelson 38:182ba91524e4 863 }
Shaun Nelson 38:182ba91524e4 864
Shaun Nelson 38:182ba91524e4 865 beaconCrc1 = ( ( uint16_t ) payload[15 + rfuOffset1 + rfuOffset2] ) & 0x00FF;
Shaun Nelson 38:182ba91524e4 866 beaconCrc1 |= ( ( uint16_t ) payload[16 + rfuOffset1 + rfuOffset2] << 8 ) & 0xFF00;
Shaun Nelson 38:182ba91524e4 867 crc1 = BeaconCrc( &payload[8 + rfuOffset1], 7 + rfuOffset2 );
Shaun Nelson 38:182ba91524e4 868
Shaun Nelson 38:182ba91524e4 869 // Validate the second crc of the beacon frame
Shaun Nelson 38:182ba91524e4 870 if( crc1 == beaconCrc1 )
Shaun Nelson 38:182ba91524e4 871 {
Shaun Nelson 38:182ba91524e4 872 // Beacon valid, apply data
Shaun Nelson 38:182ba91524e4 873 LoRaMacClassBParams.MlmeIndication->BeaconInfo.GwSpecific.InfoDesc = payload[8 + rfuOffset1];
Shaun Nelson 38:182ba91524e4 874 memcpy1( LoRaMacClassBParams.MlmeIndication->BeaconInfo.GwSpecific.Info, &payload[9 + rfuOffset1], 7 );
Shaun Nelson 38:182ba91524e4 875 beaconReceived = true;
Shaun Nelson 38:182ba91524e4 876 }
Shaun Nelson 38:182ba91524e4 877
Shaun Nelson 38:182ba91524e4 878 // Reset beacon variables, if one of the crc is valid
Shaun Nelson 38:182ba91524e4 879 if( beaconReceived == true )
Shaun Nelson 38:182ba91524e4 880 {
Shaun Nelson 38:182ba91524e4 881 BeaconCtx.LastBeaconRx = TimerGetCurrentTime( ) - Radio.TimeOnAir( MODEM_LORA, size );
Shaun Nelson 38:182ba91524e4 882 BeaconCtx.Ctrl.BeaconAcquired = 1;
Shaun Nelson 38:182ba91524e4 883 BeaconCtx.Ctrl.BeaconMode = 1;
Shaun Nelson 38:182ba91524e4 884 BeaconCtx.SymbolTimeout = BeaconCtx.Cfg.SymbolToDefault;
Shaun Nelson 38:182ba91524e4 885 BeaconState = BEACON_STATE_LOCKED;
Shaun Nelson 38:182ba91524e4 886
Shaun Nelson 38:182ba91524e4 887 LoRaMacClassBBeaconTimerEvent( );
Shaun Nelson 38:182ba91524e4 888 }
Shaun Nelson 40:f7ce84dc9363 889
Shaun Nelson 40:f7ce84dc9363 890 if( ( crc0 != beaconCrc0 ) || ( crc1 != beaconCrc1 ) )
Shaun Nelson 40:f7ce84dc9363 891 {
Shaun Nelson 40:f7ce84dc9363 892 BeaconCtx.BeaconRxError.count++;
Shaun Nelson 40:f7ce84dc9363 893 BeaconCtx.BeaconRxError.crc0 = beaconCrc0;
Shaun Nelson 40:f7ce84dc9363 894 BeaconCtx.BeaconRxError.calcCrc0 = crc0;
Shaun Nelson 40:f7ce84dc9363 895 BeaconCtx.BeaconRxError.crc1 = beaconCrc1;
Shaun Nelson 40:f7ce84dc9363 896 BeaconCtx.BeaconRxError.calcCrc1 = crc1;
Shaun Nelson 40:f7ce84dc9363 897 BeaconCtx.BeaconRxError.len = size;
Shaun Nelson 40:f7ce84dc9363 898
Shaun Nelson 40:f7ce84dc9363 899 uint8_t len = sizeof(BeaconCtx.BeaconRxError.payload);
Shaun Nelson 40:f7ce84dc9363 900 if( size < len )
Shaun Nelson 40:f7ce84dc9363 901 len = size;
Shaun Nelson 40:f7ce84dc9363 902
Shaun Nelson 40:f7ce84dc9363 903 memcpy1( BeaconCtx.BeaconRxError.payload, payload, len );
Shaun Nelson 40:f7ce84dc9363 904 BeaconCtx.BeaconRxError.len = len;
Shaun Nelson 40:f7ce84dc9363 905 }
Shaun Nelson 38:182ba91524e4 906 }
Shaun Nelson 38:182ba91524e4 907
Shaun Nelson 38:182ba91524e4 908 if( BeaconState == BEACON_STATE_RX )
Shaun Nelson 38:182ba91524e4 909 {
Shaun Nelson 38:182ba91524e4 910 BeaconState = BEACON_STATE_TIMEOUT;
Shaun Nelson 38:182ba91524e4 911 LoRaMacClassBBeaconTimerEvent( );
Shaun Nelson 38:182ba91524e4 912 }
Shaun Nelson 38:182ba91524e4 913 // Return always true, when we expect a beacon.
Shaun Nelson 38:182ba91524e4 914 beaconReceived = true;
Shaun Nelson 38:182ba91524e4 915 }
Shaun Nelson 38:182ba91524e4 916
Shaun Nelson 38:182ba91524e4 917 return beaconReceived;
Shaun Nelson 38:182ba91524e4 918 #else
Shaun Nelson 38:182ba91524e4 919 return false;
Shaun Nelson 38:182ba91524e4 920 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 921 }
Shaun Nelson 38:182ba91524e4 922
Shaun Nelson 38:182ba91524e4 923 bool LoRaMacClassBIsBeaconExpected( void )
Shaun Nelson 38:182ba91524e4 924 {
Shaun Nelson 38:182ba91524e4 925 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 926 if( ( BeaconCtx.Ctrl.AcquisitionPending == 1 ) ||
Shaun Nelson 38:182ba91524e4 927 ( BeaconCtx.Ctrl.AcquisitionTimerSet == 1 ) ||
Shaun Nelson 38:182ba91524e4 928 ( BeaconState == BEACON_STATE_RX ) )
Shaun Nelson 38:182ba91524e4 929 {
Shaun Nelson 38:182ba91524e4 930 return true;
Shaun Nelson 38:182ba91524e4 931 }
Shaun Nelson 38:182ba91524e4 932 return false;
Shaun Nelson 38:182ba91524e4 933 #else
Shaun Nelson 38:182ba91524e4 934 return false;
Shaun Nelson 38:182ba91524e4 935 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 936 }
Shaun Nelson 38:182ba91524e4 937
Shaun Nelson 38:182ba91524e4 938 bool LoRaMacClassBIsPingExpected( void )
Shaun Nelson 38:182ba91524e4 939 {
Shaun Nelson 38:182ba91524e4 940 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 941 if( PingSlotState == PINGSLOT_STATE_RX )
Shaun Nelson 38:182ba91524e4 942 {
Shaun Nelson 38:182ba91524e4 943 return true;
Shaun Nelson 38:182ba91524e4 944 }
Shaun Nelson 38:182ba91524e4 945 return false;
Shaun Nelson 38:182ba91524e4 946 #else
Shaun Nelson 38:182ba91524e4 947 return false;
Shaun Nelson 38:182ba91524e4 948 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 949 }
Shaun Nelson 38:182ba91524e4 950
Shaun Nelson 38:182ba91524e4 951 bool LoRaMacClassBIsAcquisitionPending( void )
Shaun Nelson 38:182ba91524e4 952 {
Shaun Nelson 38:182ba91524e4 953 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 954 if( BeaconCtx.Ctrl.AcquisitionPending == 1 )
Shaun Nelson 38:182ba91524e4 955 {
Shaun Nelson 38:182ba91524e4 956 return true;
Shaun Nelson 38:182ba91524e4 957 }
Shaun Nelson 38:182ba91524e4 958 return false;
Shaun Nelson 38:182ba91524e4 959 #else
Shaun Nelson 38:182ba91524e4 960 return false;
Shaun Nelson 38:182ba91524e4 961 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 962 }
Shaun Nelson 38:182ba91524e4 963
Shaun Nelson 38:182ba91524e4 964 bool LoRaMacClassBIsAcquisitionTimerSet( void )
Shaun Nelson 38:182ba91524e4 965 {
Shaun Nelson 38:182ba91524e4 966 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 967 if( BeaconCtx.Ctrl.AcquisitionTimerSet == 1 )
Shaun Nelson 38:182ba91524e4 968 {
Shaun Nelson 38:182ba91524e4 969 return true;
Shaun Nelson 38:182ba91524e4 970 }
Shaun Nelson 38:182ba91524e4 971 return false;
Shaun Nelson 38:182ba91524e4 972 #else
Shaun Nelson 38:182ba91524e4 973 return false;
Shaun Nelson 38:182ba91524e4 974 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 975 }
Shaun Nelson 38:182ba91524e4 976
Shaun Nelson 38:182ba91524e4 977 bool LoRaMacClassBIsBeaconModeActive( void )
Shaun Nelson 38:182ba91524e4 978 {
Shaun Nelson 38:182ba91524e4 979 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 980 if( BeaconCtx.Ctrl.BeaconMode == 1 )
Shaun Nelson 38:182ba91524e4 981 {
Shaun Nelson 38:182ba91524e4 982 return true;
Shaun Nelson 38:182ba91524e4 983 }
Shaun Nelson 38:182ba91524e4 984 return false;
Shaun Nelson 38:182ba91524e4 985 #else
Shaun Nelson 38:182ba91524e4 986 return false;
Shaun Nelson 38:182ba91524e4 987 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 988 }
Shaun Nelson 38:182ba91524e4 989
Shaun Nelson 38:182ba91524e4 990 void LoRaMacClassBSetPingSlotInfo( uint8_t periodicity )
Shaun Nelson 38:182ba91524e4 991 {
Shaun Nelson 38:182ba91524e4 992 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 993 PingSlotCtx.PingNb = 128 / ( 1 << periodicity );
Shaun Nelson 38:182ba91524e4 994 PingSlotCtx.PingPeriod = BeaconCtx.Cfg.WindowSlots / PingSlotCtx.PingNb;
Shaun Nelson 38:182ba91524e4 995 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 996 }
Shaun Nelson 38:182ba91524e4 997
Shaun Nelson 38:182ba91524e4 998 void LoRaMacClassBHaltBeaconing( void )
Shaun Nelson 38:182ba91524e4 999 {
Shaun Nelson 38:182ba91524e4 1000 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1001 if( ( BeaconState == BEACON_STATE_TIMEOUT ) ||
Shaun Nelson 38:182ba91524e4 1002 ( BeaconState == BEACON_STATE_SWITCH_CLASS ) )
Shaun Nelson 38:182ba91524e4 1003 {
Shaun Nelson 38:182ba91524e4 1004 // Update the state machine before halt
Shaun Nelson 38:182ba91524e4 1005 LoRaMacClassBBeaconTimerEvent( );
Shaun Nelson 38:182ba91524e4 1006 }
Shaun Nelson 38:182ba91524e4 1007
Shaun Nelson 38:182ba91524e4 1008 // Halt beacon state machine
Shaun Nelson 38:182ba91524e4 1009 BeaconState = BEACON_STATE_HALT;
Shaun Nelson 38:182ba91524e4 1010
Shaun Nelson 38:182ba91524e4 1011 // Halt ping slot state machine
Shaun Nelson 38:182ba91524e4 1012 TimerStop( &BeaconTimer );
Shaun Nelson 40:f7ce84dc9363 1013 BeaconEventTime = 0;
Shaun Nelson 38:182ba91524e4 1014
Shaun Nelson 38:182ba91524e4 1015 // Halt ping slot state machine
Shaun Nelson 38:182ba91524e4 1016 TimerStop( &PingSlotTimer );
Shaun Nelson 38:182ba91524e4 1017
Shaun Nelson 38:182ba91524e4 1018 // Halt multicast ping slot state machine
Shaun Nelson 38:182ba91524e4 1019 TimerStop( &MulticastSlotTimer );
Shaun Nelson 38:182ba91524e4 1020 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1021 }
Shaun Nelson 38:182ba91524e4 1022
Shaun Nelson 38:182ba91524e4 1023 void LoRaMacClassBResumeBeaconing( void )
Shaun Nelson 38:182ba91524e4 1024 {
Shaun Nelson 38:182ba91524e4 1025 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1026 if( BeaconState == BEACON_STATE_HALT )
Shaun Nelson 38:182ba91524e4 1027 {
Shaun Nelson 38:182ba91524e4 1028 BeaconCtx.Ctrl.ResumeBeaconing = 1;
Shaun Nelson 38:182ba91524e4 1029
Shaun Nelson 38:182ba91524e4 1030 // Set default state
Shaun Nelson 38:182ba91524e4 1031 BeaconState = BEACON_STATE_LOCKED;
Shaun Nelson 38:182ba91524e4 1032
Shaun Nelson 38:182ba91524e4 1033 if( BeaconCtx.Ctrl.BeaconAcquired == 0 )
Shaun Nelson 38:182ba91524e4 1034 {
Shaun Nelson 38:182ba91524e4 1035 // Set the default state for beacon less operation
Shaun Nelson 38:182ba91524e4 1036 BeaconState = BEACON_STATE_REACQUISITION;
Shaun Nelson 38:182ba91524e4 1037 }
Shaun Nelson 38:182ba91524e4 1038 TimerSetValue( &BeaconTimer, 1 );
Shaun Nelson 38:182ba91524e4 1039 TimerStart( &BeaconTimer );
Shaun Nelson 40:f7ce84dc9363 1040 BeaconEventTime = 1;
Shaun Nelson 38:182ba91524e4 1041 }
Shaun Nelson 38:182ba91524e4 1042 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1043 }
Shaun Nelson 38:182ba91524e4 1044
Shaun Nelson 38:182ba91524e4 1045 LoRaMacStatus_t LoRaMacClassBSwitchClass( DeviceClass_t nextClass )
Shaun Nelson 38:182ba91524e4 1046 {
Shaun Nelson 38:182ba91524e4 1047 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1048 if( nextClass == CLASS_B )
Shaun Nelson 38:182ba91524e4 1049 {// Switch to from class a to class b
Shaun Nelson 38:182ba91524e4 1050 if( ( BeaconCtx.Ctrl.BeaconMode == 1 ) && ( PingSlotCtx.Ctrl.Assigned == 1 ) )
Shaun Nelson 38:182ba91524e4 1051 {
Shaun Nelson 38:182ba91524e4 1052 return LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1053 }
Shaun Nelson 38:182ba91524e4 1054 }
Shaun Nelson 38:182ba91524e4 1055 if( nextClass == CLASS_A )
Shaun Nelson 38:182ba91524e4 1056 {// Switch from class b to class a
Shaun Nelson 38:182ba91524e4 1057 BeaconState = BEACON_STATE_ACQUISITION;
Shaun Nelson 38:182ba91524e4 1058 return LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1059 }
Shaun Nelson 38:182ba91524e4 1060 return LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 1061 #else
Shaun Nelson 38:182ba91524e4 1062 return LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 1063 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1064 }
Shaun Nelson 38:182ba91524e4 1065
Shaun Nelson 38:182ba91524e4 1066 LoRaMacStatus_t LoRaMacClassBMibGetRequestConfirm( MibRequestConfirm_t *mibGet )
Shaun Nelson 38:182ba91524e4 1067 {
Shaun Nelson 38:182ba91524e4 1068 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1069 LoRaMacStatus_t status;
Shaun Nelson 38:182ba91524e4 1070
Shaun Nelson 38:182ba91524e4 1071 switch( mibGet->Type )
Shaun Nelson 38:182ba91524e4 1072 {
Shaun Nelson 38:182ba91524e4 1073 case MIB_BEACON_INTERVAL:
Shaun Nelson 38:182ba91524e4 1074 {
Shaun Nelson 38:182ba91524e4 1075 mibGet->Param.BeaconInterval = BeaconCtx.Cfg.Interval;
Shaun Nelson 38:182ba91524e4 1076 break;
Shaun Nelson 38:182ba91524e4 1077 }
Shaun Nelson 38:182ba91524e4 1078 case MIB_BEACON_RESERVED:
Shaun Nelson 38:182ba91524e4 1079 {
Shaun Nelson 38:182ba91524e4 1080 mibGet->Param.BeaconReserved = BeaconCtx.Cfg.Reserved;
Shaun Nelson 38:182ba91524e4 1081 break;
Shaun Nelson 38:182ba91524e4 1082 }
Shaun Nelson 38:182ba91524e4 1083 case MIB_BEACON_GUARD:
Shaun Nelson 38:182ba91524e4 1084 {
Shaun Nelson 38:182ba91524e4 1085 mibGet->Param.BeaconGuard = BeaconCtx.Cfg.Guard;
Shaun Nelson 38:182ba91524e4 1086 break;
Shaun Nelson 38:182ba91524e4 1087 }
Shaun Nelson 38:182ba91524e4 1088 case MIB_BEACON_WINDOW:
Shaun Nelson 38:182ba91524e4 1089 {
Shaun Nelson 38:182ba91524e4 1090 mibGet->Param.BeaconWindow = BeaconCtx.Cfg.Window;
Shaun Nelson 38:182ba91524e4 1091 break;
Shaun Nelson 38:182ba91524e4 1092 }
Shaun Nelson 38:182ba91524e4 1093 case MIB_BEACON_WINDOW_SLOTS:
Shaun Nelson 38:182ba91524e4 1094 {
Shaun Nelson 38:182ba91524e4 1095 mibGet->Param.BeaconWindowSlots = BeaconCtx.Cfg.WindowSlots;
Shaun Nelson 38:182ba91524e4 1096 break;
Shaun Nelson 38:182ba91524e4 1097 }
Shaun Nelson 38:182ba91524e4 1098 case MIB_PING_SLOT_WINDOW:
Shaun Nelson 38:182ba91524e4 1099 {
Shaun Nelson 38:182ba91524e4 1100 mibGet->Param.PingSlotWindow = PingSlotCtx.Cfg.PingSlotWindow;
Shaun Nelson 38:182ba91524e4 1101 break;
Shaun Nelson 38:182ba91524e4 1102 }
Shaun Nelson 38:182ba91524e4 1103 case MIB_BEACON_SYMBOL_TO_DEFAULT:
Shaun Nelson 38:182ba91524e4 1104 {
Shaun Nelson 38:182ba91524e4 1105 mibGet->Param.BeaconSymbolToDefault = BeaconCtx.Cfg.SymbolToDefault;
Shaun Nelson 38:182ba91524e4 1106 break;
Shaun Nelson 38:182ba91524e4 1107 }
Shaun Nelson 38:182ba91524e4 1108 case MIB_BEACON_SYMBOL_TO_EXPANSION_MAX:
Shaun Nelson 38:182ba91524e4 1109 {
Shaun Nelson 38:182ba91524e4 1110 mibGet->Param.BeaconSymbolToExpansionMax = BeaconCtx.Cfg.SymbolToExpansionMax;
Shaun Nelson 38:182ba91524e4 1111 break;
Shaun Nelson 38:182ba91524e4 1112 }
Shaun Nelson 38:182ba91524e4 1113 case MIB_PING_SLOT_SYMBOL_TO_EXPANSION_MAX:
Shaun Nelson 38:182ba91524e4 1114 {
Shaun Nelson 38:182ba91524e4 1115 mibGet->Param.PingSlotSymbolToExpansionMax = PingSlotCtx.Cfg.SymbolToExpansionMax;
Shaun Nelson 38:182ba91524e4 1116 break;
Shaun Nelson 38:182ba91524e4 1117 }
Shaun Nelson 38:182ba91524e4 1118 case MIB_BEACON_SYMBOL_TO_EXPANSION_FACTOR:
Shaun Nelson 38:182ba91524e4 1119 {
Shaun Nelson 38:182ba91524e4 1120 mibGet->Param.BeaconSymbolToExpansionFactor = BeaconCtx.Cfg.SymbolToExpansionFactor;
Shaun Nelson 38:182ba91524e4 1121 break;
Shaun Nelson 38:182ba91524e4 1122 }
Shaun Nelson 38:182ba91524e4 1123 case MIB_PING_SLOT_SYMBOL_TO_EXPANSION_FACTOR:
Shaun Nelson 38:182ba91524e4 1124 {
Shaun Nelson 38:182ba91524e4 1125 mibGet->Param.PingSlotSymbolToExpansionFactor = PingSlotCtx.Cfg.SymbolToExpansionFactor;
Shaun Nelson 38:182ba91524e4 1126 break;
Shaun Nelson 38:182ba91524e4 1127 }
Shaun Nelson 38:182ba91524e4 1128 case MIB_MAX_BEACON_LESS_PERIOD:
Shaun Nelson 38:182ba91524e4 1129 {
Shaun Nelson 38:182ba91524e4 1130 mibGet->Param.MaxBeaconLessPeriod = BeaconCtx.Cfg.MaxBeaconLessPeriod;
Shaun Nelson 38:182ba91524e4 1131 break;
Shaun Nelson 38:182ba91524e4 1132 }
Shaun Nelson 38:182ba91524e4 1133 default:
Shaun Nelson 38:182ba91524e4 1134 {
Shaun Nelson 38:182ba91524e4 1135 status = LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 1136 break;
Shaun Nelson 38:182ba91524e4 1137 }
Shaun Nelson 38:182ba91524e4 1138 }
Shaun Nelson 38:182ba91524e4 1139 return status;
Shaun Nelson 38:182ba91524e4 1140 #else
Shaun Nelson 38:182ba91524e4 1141 return LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 1142 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1143 }
Shaun Nelson 38:182ba91524e4 1144
Shaun Nelson 38:182ba91524e4 1145 LoRaMacStatus_t LoRaMacMibClassBSetRequestConfirm( MibRequestConfirm_t *mibSet )
Shaun Nelson 38:182ba91524e4 1146 {
Shaun Nelson 38:182ba91524e4 1147 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1148 LoRaMacStatus_t status;
Shaun Nelson 38:182ba91524e4 1149
Shaun Nelson 38:182ba91524e4 1150 switch( mibSet->Type )
Shaun Nelson 38:182ba91524e4 1151 {
Shaun Nelson 38:182ba91524e4 1152 case MIB_BEACON_INTERVAL:
Shaun Nelson 38:182ba91524e4 1153 {
Shaun Nelson 38:182ba91524e4 1154 BeaconCtx.Cfg.Interval = mibSet->Param.BeaconInterval;
Shaun Nelson 38:182ba91524e4 1155 break;
Shaun Nelson 38:182ba91524e4 1156 }
Shaun Nelson 38:182ba91524e4 1157 case MIB_BEACON_RESERVED:
Shaun Nelson 38:182ba91524e4 1158 {
Shaun Nelson 38:182ba91524e4 1159 BeaconCtx.Cfg.Reserved = mibSet->Param.BeaconReserved;
Shaun Nelson 38:182ba91524e4 1160 break;
Shaun Nelson 38:182ba91524e4 1161 }
Shaun Nelson 38:182ba91524e4 1162 case MIB_BEACON_GUARD:
Shaun Nelson 38:182ba91524e4 1163 {
Shaun Nelson 38:182ba91524e4 1164 BeaconCtx.Cfg.Guard = mibSet->Param.BeaconGuard;
Shaun Nelson 38:182ba91524e4 1165 break;
Shaun Nelson 38:182ba91524e4 1166 }
Shaun Nelson 38:182ba91524e4 1167 case MIB_BEACON_WINDOW:
Shaun Nelson 38:182ba91524e4 1168 {
Shaun Nelson 38:182ba91524e4 1169 BeaconCtx.Cfg.Window = mibSet->Param.BeaconWindow;
Shaun Nelson 38:182ba91524e4 1170 break;
Shaun Nelson 38:182ba91524e4 1171 }
Shaun Nelson 38:182ba91524e4 1172 case MIB_BEACON_WINDOW_SLOTS:
Shaun Nelson 38:182ba91524e4 1173 {
Shaun Nelson 38:182ba91524e4 1174 BeaconCtx.Cfg.WindowSlots = mibSet->Param.BeaconWindowSlots;
Shaun Nelson 38:182ba91524e4 1175 break;
Shaun Nelson 38:182ba91524e4 1176 }
Shaun Nelson 38:182ba91524e4 1177 case MIB_PING_SLOT_WINDOW:
Shaun Nelson 38:182ba91524e4 1178 {
Shaun Nelson 38:182ba91524e4 1179 PingSlotCtx.Cfg.PingSlotWindow = mibSet->Param.PingSlotWindow;
Shaun Nelson 38:182ba91524e4 1180 break;
Shaun Nelson 38:182ba91524e4 1181 }
Shaun Nelson 38:182ba91524e4 1182 case MIB_BEACON_SYMBOL_TO_DEFAULT:
Shaun Nelson 38:182ba91524e4 1183 {
Shaun Nelson 38:182ba91524e4 1184 BeaconCtx.Cfg.SymbolToDefault = mibSet->Param.BeaconSymbolToDefault;
Shaun Nelson 38:182ba91524e4 1185 break;
Shaun Nelson 38:182ba91524e4 1186 }
Shaun Nelson 38:182ba91524e4 1187 case MIB_BEACON_SYMBOL_TO_EXPANSION_MAX:
Shaun Nelson 38:182ba91524e4 1188 {
Shaun Nelson 38:182ba91524e4 1189 BeaconCtx.Cfg.SymbolToExpansionMax = mibSet->Param.BeaconSymbolToExpansionMax;
Shaun Nelson 38:182ba91524e4 1190 break;
Shaun Nelson 38:182ba91524e4 1191 }
Shaun Nelson 38:182ba91524e4 1192 case MIB_PING_SLOT_SYMBOL_TO_EXPANSION_MAX:
Shaun Nelson 38:182ba91524e4 1193 {
Shaun Nelson 38:182ba91524e4 1194 PingSlotCtx.Cfg.SymbolToExpansionMax = mibSet->Param.PingSlotSymbolToExpansionMax;
Shaun Nelson 38:182ba91524e4 1195 break;
Shaun Nelson 38:182ba91524e4 1196 }
Shaun Nelson 38:182ba91524e4 1197 case MIB_BEACON_SYMBOL_TO_EXPANSION_FACTOR:
Shaun Nelson 38:182ba91524e4 1198 {
Shaun Nelson 38:182ba91524e4 1199 BeaconCtx.Cfg.SymbolToExpansionFactor = mibSet->Param.BeaconSymbolToExpansionFactor;
Shaun Nelson 38:182ba91524e4 1200 break;
Shaun Nelson 38:182ba91524e4 1201 }
Shaun Nelson 38:182ba91524e4 1202 case MIB_PING_SLOT_SYMBOL_TO_EXPANSION_FACTOR:
Shaun Nelson 38:182ba91524e4 1203 {
Shaun Nelson 38:182ba91524e4 1204 PingSlotCtx.Cfg.SymbolToExpansionFactor = mibSet->Param.PingSlotSymbolToExpansionFactor;
Shaun Nelson 38:182ba91524e4 1205 break;
Shaun Nelson 38:182ba91524e4 1206 }
Shaun Nelson 38:182ba91524e4 1207 case MIB_MAX_BEACON_LESS_PERIOD:
Shaun Nelson 38:182ba91524e4 1208 {
Shaun Nelson 38:182ba91524e4 1209 BeaconCtx.Cfg.MaxBeaconLessPeriod = mibSet->Param.MaxBeaconLessPeriod;
Shaun Nelson 38:182ba91524e4 1210 break;
Shaun Nelson 38:182ba91524e4 1211 }
Shaun Nelson 38:182ba91524e4 1212 default:
Shaun Nelson 38:182ba91524e4 1213 {
Shaun Nelson 38:182ba91524e4 1214 status = LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 1215 break;
Shaun Nelson 38:182ba91524e4 1216 }
Shaun Nelson 38:182ba91524e4 1217 }
Shaun Nelson 38:182ba91524e4 1218 return status;
Shaun Nelson 38:182ba91524e4 1219 #else
Shaun Nelson 38:182ba91524e4 1220 return LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 1221 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1222 }
Shaun Nelson 38:182ba91524e4 1223
Shaun Nelson 38:182ba91524e4 1224 void LoRaMacClassBPingSlotInfoAns( void )
Shaun Nelson 38:182ba91524e4 1225 {
Shaun Nelson 38:182ba91524e4 1226 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1227 uint8_t index = LORA_MAC_MLME_CONFIRM_QUEUE_LEN;
Shaun Nelson 38:182ba91524e4 1228
Shaun Nelson 38:182ba91524e4 1229 index = LoRaMacClassBCallbacks.GetMlmeConfrimIndex( LoRaMacClassBParams.MlmeConfirmQueue, MLME_PING_SLOT_INFO );
Shaun Nelson 38:182ba91524e4 1230 if( index < LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
Shaun Nelson 38:182ba91524e4 1231 {
Shaun Nelson 38:182ba91524e4 1232 LoRaMacClassBParams.MlmeConfirmQueue[index].Status = LORAMAC_EVENT_INFO_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1233 PingSlotCtx.Ctrl.Assigned = 1;
Shaun Nelson 38:182ba91524e4 1234 }
Shaun Nelson 38:182ba91524e4 1235 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1236 }
Shaun Nelson 38:182ba91524e4 1237
Shaun Nelson 38:182ba91524e4 1238 uint8_t LoRaMacClassBPingSlotChannelReq( uint8_t datarate, uint32_t frequency )
Shaun Nelson 38:182ba91524e4 1239 {
Shaun Nelson 38:182ba91524e4 1240 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1241 uint8_t status = 0x03;
Shaun Nelson 38:182ba91524e4 1242 VerifyParams_t verify;
Shaun Nelson 38:182ba91524e4 1243 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 1244 PhyParam_t phyParam;
Shaun Nelson 38:182ba91524e4 1245
Shaun Nelson 38:182ba91524e4 1246 if( frequency != 0 )
Shaun Nelson 38:182ba91524e4 1247 {
Shaun Nelson 38:182ba91524e4 1248 if( Radio.CheckRfFrequency( frequency ) == false )
Shaun Nelson 38:182ba91524e4 1249 {
Shaun Nelson 38:182ba91524e4 1250 status &= 0xFE; // Channel frequency KO
Shaun Nelson 38:182ba91524e4 1251 }
Shaun Nelson 38:182ba91524e4 1252
Shaun Nelson 38:182ba91524e4 1253 verify.DatarateParams.Datarate = datarate;
Shaun Nelson 38:182ba91524e4 1254 verify.DatarateParams.DownlinkDwellTime = LoRaMacClassBParams.LoRaMacParams->DownlinkDwellTime;
Shaun Nelson 38:182ba91524e4 1255
Shaun Nelson 38:182ba91524e4 1256 if( RegionVerify( *LoRaMacClassBParams.LoRaMacRegion, &verify, PHY_RX_DR ) == false )
Shaun Nelson 38:182ba91524e4 1257 {
Shaun Nelson 38:182ba91524e4 1258 status &= 0xFD; // Datarate range KO
Shaun Nelson 38:182ba91524e4 1259 }
Shaun Nelson 38:182ba91524e4 1260
Shaun Nelson 38:182ba91524e4 1261 if( status == 0x03 )
Shaun Nelson 38:182ba91524e4 1262 {
Shaun Nelson 38:182ba91524e4 1263 PingSlotCtx.Ctrl.CustomFreq = 1;
Shaun Nelson 38:182ba91524e4 1264 PingSlotCtx.Frequency = frequency;
Shaun Nelson 38:182ba91524e4 1265 PingSlotCtx.Datarate = datarate;
Shaun Nelson 38:182ba91524e4 1266 }
Shaun Nelson 38:182ba91524e4 1267 }
Shaun Nelson 38:182ba91524e4 1268 else
Shaun Nelson 38:182ba91524e4 1269 {
Shaun Nelson 38:182ba91524e4 1270 getPhy.Attribute = PHY_BEACON_CHANNEL_DR;
Shaun Nelson 38:182ba91524e4 1271 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 1272
Shaun Nelson 38:182ba91524e4 1273 PingSlotCtx.Ctrl.CustomFreq = 0;
Shaun Nelson 38:182ba91524e4 1274 PingSlotCtx.Datarate = phyParam.Value;
Shaun Nelson 38:182ba91524e4 1275 }
Shaun Nelson 38:182ba91524e4 1276 return status;
Shaun Nelson 38:182ba91524e4 1277 #else
Shaun Nelson 38:182ba91524e4 1278 return 0;
Shaun Nelson 38:182ba91524e4 1279 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1280 }
Shaun Nelson 38:182ba91524e4 1281
Shaun Nelson 38:182ba91524e4 1282 void LoRaMacClassBBeaconTimingAns( uint16_t beaconTimingDelay, uint8_t beaconTimingChannel )
Shaun Nelson 38:182ba91524e4 1283 {
Shaun Nelson 38:182ba91524e4 1284 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1285 uint8_t index = LORA_MAC_MLME_CONFIRM_QUEUE_LEN;
Shaun Nelson 38:182ba91524e4 1286 TimerTime_t currentTime = TimerGetCurrentTime( );
Shaun Nelson 38:182ba91524e4 1287
Shaun Nelson 38:182ba91524e4 1288 BeaconCtx.BeaconTimingDelay = ( BeaconCtx.Cfg.DelayBeaconTimingAns * beaconTimingDelay );
Shaun Nelson 38:182ba91524e4 1289 BeaconCtx.BeaconTimingChannel = beaconTimingChannel;
Shaun Nelson 38:182ba91524e4 1290
Shaun Nelson 38:182ba91524e4 1291 index = LoRaMacClassBCallbacks.GetMlmeConfrimIndex( LoRaMacClassBParams.MlmeConfirmQueue, MLME_BEACON_TIMING );
Shaun Nelson 38:182ba91524e4 1292 if( index < LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
Shaun Nelson 38:182ba91524e4 1293 {
Shaun Nelson 38:182ba91524e4 1294 if( BeaconCtx.BeaconTimingDelay > BeaconCtx.Cfg.Interval )
Shaun Nelson 38:182ba91524e4 1295 {
Shaun Nelson 38:182ba91524e4 1296 // We missed the beacon already
Shaun Nelson 38:182ba91524e4 1297 BeaconCtx.BeaconTimingDelay = 0;
Shaun Nelson 38:182ba91524e4 1298 BeaconCtx.BeaconTimingChannel = 0;
Shaun Nelson 38:182ba91524e4 1299 LoRaMacClassBParams.MlmeConfirmQueue[index].Status = LORAMAC_EVENT_INFO_STATUS_BEACON_NOT_FOUND;
Shaun Nelson 38:182ba91524e4 1300 }
Shaun Nelson 38:182ba91524e4 1301 else
Shaun Nelson 38:182ba91524e4 1302 {
Shaun Nelson 38:182ba91524e4 1303 BeaconCtx.Ctrl.BeaconDelaySet = 1;
Shaun Nelson 38:182ba91524e4 1304 BeaconCtx.Ctrl.BeaconChannelSet = 1;
Shaun Nelson 38:182ba91524e4 1305 BeaconCtx.NextBeaconRx = currentTime + BeaconCtx.BeaconTimingDelay;
Shaun Nelson 38:182ba91524e4 1306 LoRaMacClassBParams.MlmeConfirmQueue[index].Status = LORAMAC_EVENT_INFO_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1307 }
Shaun Nelson 38:182ba91524e4 1308
Shaun Nelson 38:182ba91524e4 1309 LoRaMacClassBParams.MlmeConfirm->BeaconTimingDelay = BeaconCtx.BeaconTimingDelay;
Shaun Nelson 38:182ba91524e4 1310 LoRaMacClassBParams.MlmeConfirm->BeaconTimingChannel = BeaconCtx.BeaconTimingChannel;
Shaun Nelson 38:182ba91524e4 1311 }
Shaun Nelson 38:182ba91524e4 1312 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1313 }
Shaun Nelson 38:182ba91524e4 1314
Shaun Nelson 38:182ba91524e4 1315 bool LoRaMacClassBBeaconFreqReq( uint32_t frequency )
Shaun Nelson 38:182ba91524e4 1316 {
Shaun Nelson 38:182ba91524e4 1317 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1318 if( frequency != 0 )
Shaun Nelson 38:182ba91524e4 1319 {
Shaun Nelson 38:182ba91524e4 1320 if( Radio.CheckRfFrequency( frequency ) == true )
Shaun Nelson 38:182ba91524e4 1321 {
Shaun Nelson 38:182ba91524e4 1322 BeaconCtx.Ctrl.CustomFreq = 1;
Shaun Nelson 38:182ba91524e4 1323 BeaconCtx.Frequency = frequency;
Shaun Nelson 38:182ba91524e4 1324 return true;
Shaun Nelson 38:182ba91524e4 1325 }
Shaun Nelson 38:182ba91524e4 1326 }
Shaun Nelson 38:182ba91524e4 1327 else
Shaun Nelson 38:182ba91524e4 1328 {
Shaun Nelson 38:182ba91524e4 1329 BeaconCtx.Ctrl.CustomFreq = 0;
Shaun Nelson 38:182ba91524e4 1330 return true;
Shaun Nelson 38:182ba91524e4 1331 }
Shaun Nelson 38:182ba91524e4 1332 return false;
Shaun Nelson 38:182ba91524e4 1333 #else
Shaun Nelson 38:182ba91524e4 1334 return false;
Shaun Nelson 38:182ba91524e4 1335 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1336 }
Shaun Nelson 38:182ba91524e4 1337
Shaun Nelson 38:182ba91524e4 1338 TimerTime_t LoRaMacClassBGetBeaconReservedTime( void )
Shaun Nelson 38:182ba91524e4 1339 {
Shaun Nelson 38:182ba91524e4 1340 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1341 return BeaconCtx.Cfg.Reserved;
Shaun Nelson 38:182ba91524e4 1342 #else
Shaun Nelson 38:182ba91524e4 1343 return 0;
Shaun Nelson 38:182ba91524e4 1344 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1345 }
Shaun Nelson 38:182ba91524e4 1346
Shaun Nelson 38:182ba91524e4 1347 TimerTime_t LoRaMacClassBGetPingSlotWinTime( void )
Shaun Nelson 38:182ba91524e4 1348 {
Shaun Nelson 38:182ba91524e4 1349 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1350 return PingSlotCtx.Cfg.PingSlotWindow;
Shaun Nelson 38:182ba91524e4 1351 #else
Shaun Nelson 38:182ba91524e4 1352 return 0;
Shaun Nelson 38:182ba91524e4 1353 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1354 }
Shaun Nelson 38:182ba91524e4 1355
Shaun Nelson 38:182ba91524e4 1356 TimerTime_t LoRaMacClassBIsUplinkCollision( TimerTime_t txTimeOnAir )
Shaun Nelson 38:182ba91524e4 1357 {
Shaun Nelson 38:182ba91524e4 1358 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1359 TimerTime_t currentTime = TimerGetCurrentTime( );
Shaun Nelson 38:182ba91524e4 1360 TimerTime_t beaconReserved = 0;
Shaun Nelson 38:182ba91524e4 1361
Shaun Nelson 38:182ba91524e4 1362 beaconReserved = BeaconCtx.NextBeaconRx -
Shaun Nelson 38:182ba91524e4 1363 BeaconCtx.Cfg.Guard -
Shaun Nelson 38:182ba91524e4 1364 LoRaMacClassBParams.LoRaMacParams->ReceiveDelay1 -
Shaun Nelson 38:182ba91524e4 1365 LoRaMacClassBParams.LoRaMacParams->ReceiveDelay2 -
Shaun Nelson 38:182ba91524e4 1366 txTimeOnAir;
Shaun Nelson 38:182ba91524e4 1367
Shaun Nelson 38:182ba91524e4 1368 // Check if the next beacon will be received during the next uplink.
Shaun Nelson 38:182ba91524e4 1369 if( ( currentTime >= beaconReserved ) && ( currentTime < ( BeaconCtx.NextBeaconRx + BeaconCtx.Cfg.Reserved ) ) )
Shaun Nelson 38:182ba91524e4 1370 {// Next beacon will be sent during the next uplink.
Shaun Nelson 38:182ba91524e4 1371 return BeaconCtx.Cfg.Reserved;
Shaun Nelson 38:182ba91524e4 1372 }
Shaun Nelson 38:182ba91524e4 1373 return 0;
Shaun Nelson 38:182ba91524e4 1374 #else
Shaun Nelson 38:182ba91524e4 1375 return 0;
Shaun Nelson 38:182ba91524e4 1376 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1377 }