Senet / LoRaWAN-lib

Fork of LoRaWAN-lib by canuck lehead

Committer:
Shaun Nelson
Date:
Thu Sep 21 17:02:39 2017 -0400
Branch:
class_b
Revision:
48:81c0f4c4dd2c
Parent:
40:f7ce84dc9363
Initialize PingSlot datarate
Add control to adjust beacon rx time
Add debug

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 48:81c0f4c4dd2c 45 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 48:81c0f4c4dd2c 250
Shaun Nelson 48:81c0f4c4dd2c 251 getPhy.Attribute = PHY_BEACON_CHANNEL_DR;
Shaun Nelson 48:81c0f4c4dd2c 252 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 48:81c0f4c4dd2c 253 PingSlotCtx.Datarate = phyParam.Value;
Shaun Nelson 38:182ba91524e4 254 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 255 }
Shaun Nelson 38:182ba91524e4 256
Shaun Nelson 38:182ba91524e4 257 void LoRaMacClassBSetBeaconState( BeaconState_t beaconState )
Shaun Nelson 38:182ba91524e4 258 {
Shaun Nelson 38:182ba91524e4 259 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 260 BeaconState = beaconState;
Shaun Nelson 38:182ba91524e4 261 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 262 }
Shaun Nelson 38:182ba91524e4 263
Shaun Nelson 38:182ba91524e4 264 void LoRaMacClassBSetPingSlotState( PingSlotState_t pingSlotState )
Shaun Nelson 38:182ba91524e4 265 {
Shaun Nelson 38:182ba91524e4 266 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 267 PingSlotState = pingSlotState;
Shaun Nelson 38:182ba91524e4 268 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 269 }
Shaun Nelson 38:182ba91524e4 270
Shaun Nelson 40:f7ce84dc9363 271 static TimerTime_t BeaconEventTime = 0;
Shaun Nelson 40:f7ce84dc9363 272
Shaun Nelson 40:f7ce84dc9363 273 TimerTime_t LoRaMacClassBGetBeaconEventTime( )
Shaun Nelson 40:f7ce84dc9363 274 {
Shaun Nelson 40:f7ce84dc9363 275 return BeaconEventTime;
Shaun Nelson 40:f7ce84dc9363 276 }
Shaun Nelson 40:f7ce84dc9363 277
Shaun Nelson 48:81c0f4c4dd2c 278 extern uint32_t BeaconPingSlotAnsAdjust;
Shaun Nelson 48:81c0f4c4dd2c 279
Shaun Nelson 38:182ba91524e4 280 void LoRaMacClassBBeaconTimerEvent( void )
Shaun Nelson 38:182ba91524e4 281 {
Shaun Nelson 38:182ba91524e4 282 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 283 RxBeaconSetup_t rxBeaconSetup;
Shaun Nelson 38:182ba91524e4 284 bool beaconChannelSet = false;
Shaun Nelson 38:182ba91524e4 285 uint8_t index = 0;
Shaun Nelson 38:182ba91524e4 286 bool activateTimer = false;
Shaun Nelson 38:182ba91524e4 287 TimerTime_t beaconEventTime = 1;
Shaun Nelson 38:182ba91524e4 288 TimerTime_t currentTime = TimerGetCurrentTime( );
Shaun Nelson 38:182ba91524e4 289
Shaun Nelson 38:182ba91524e4 290 TimerStop( &BeaconTimer );
Shaun Nelson 40:f7ce84dc9363 291 BeaconEventTime = 0;
Shaun Nelson 38:182ba91524e4 292
Shaun Nelson 38:182ba91524e4 293 // Beacon state machine
Shaun Nelson 38:182ba91524e4 294 switch( BeaconState )
Shaun Nelson 38:182ba91524e4 295 {
Shaun Nelson 38:182ba91524e4 296 case BEACON_STATE_ACQUISITION:
Shaun Nelson 38:182ba91524e4 297 {
Shaun Nelson 38:182ba91524e4 298 activateTimer = true;
Shaun Nelson 38:182ba91524e4 299
Shaun Nelson 38:182ba91524e4 300 if( BeaconCtx.Ctrl.AcquisitionPending == 1 )
Shaun Nelson 38:182ba91524e4 301 {
Shaun Nelson 38:182ba91524e4 302 Radio.Sleep();
Shaun Nelson 38:182ba91524e4 303 BeaconState = BEACON_STATE_SWITCH_CLASS;
Shaun Nelson 38:182ba91524e4 304 }
Shaun Nelson 38:182ba91524e4 305 else
Shaun Nelson 38:182ba91524e4 306 {
Shaun Nelson 38:182ba91524e4 307 // Default symbol timeouts
Shaun Nelson 38:182ba91524e4 308 BeaconCtx.SymbolTimeout = BeaconCtx.Cfg.SymbolToDefault;
Shaun Nelson 38:182ba91524e4 309 PingSlotCtx.SymbolTimeout = BeaconCtx.Cfg.SymbolToDefault;
Shaun Nelson 38:182ba91524e4 310
Shaun Nelson 38:182ba91524e4 311 if( BeaconCtx.Ctrl.BeaconDelaySet == 1 )
Shaun Nelson 38:182ba91524e4 312 {
Shaun Nelson 38:182ba91524e4 313 if( BeaconCtx.BeaconTimingDelay > 0 )
Shaun Nelson 38:182ba91524e4 314 {
Shaun Nelson 38:182ba91524e4 315 if( BeaconCtx.NextBeaconRx > currentTime )
Shaun Nelson 38:182ba91524e4 316 {
Shaun Nelson 38:182ba91524e4 317 BeaconCtx.Ctrl.AcquisitionTimerSet = 1;
Shaun Nelson 48:81c0f4c4dd2c 318 beaconEventTime = TimerTempCompensation( BeaconCtx.NextBeaconRx - currentTime, BeaconCtx.Temperature ) - 2000;
Shaun Nelson 48:81c0f4c4dd2c 319 BeaconCtx.BeaconAcqTime = beaconEventTime + currentTime;
Shaun Nelson 38:182ba91524e4 320 }
Shaun Nelson 38:182ba91524e4 321 else
Shaun Nelson 38:182ba91524e4 322 {
Shaun Nelson 38:182ba91524e4 323 BeaconCtx.Ctrl.BeaconDelaySet = 0;
Shaun Nelson 38:182ba91524e4 324 BeaconCtx.Ctrl.AcquisitionPending = 1;
Shaun Nelson 38:182ba91524e4 325 BeaconCtx.Ctrl.AcquisitionTimerSet = 0;
Shaun Nelson 48:81c0f4c4dd2c 326
Shaun Nelson 48:81c0f4c4dd2c 327 // SKN - Closing Beacon Rx window after 10 seconds instead of miss and wait of 128 seconds
Shaun Nelson 48:81c0f4c4dd2c 328 beaconEventTime = 10000;
Shaun Nelson 48:81c0f4c4dd2c 329 // beaconEventTime = BeaconCtx.Cfg.Interval;
Shaun Nelson 38:182ba91524e4 330
Shaun Nelson 38:182ba91524e4 331 rxBeaconSetup.SymbolTimeout = BeaconCtx.SymbolTimeout;
Shaun Nelson 38:182ba91524e4 332 rxBeaconSetup.RxTime = 0;
Shaun Nelson 38:182ba91524e4 333 rxBeaconSetup.DeviceAddress = *LoRaMacClassBParams.LoRaMacDevAddr;
Shaun Nelson 38:182ba91524e4 334 rxBeaconSetup.BeaconTimingChannel = BeaconCtx.BeaconTimingChannel;
Shaun Nelson 38:182ba91524e4 335 rxBeaconSetup.CustomFrequencyEnabled = BeaconCtx.Ctrl.CustomFreq;
Shaun Nelson 38:182ba91524e4 336 rxBeaconSetup.BeaconChannelSet = BeaconCtx.Ctrl.BeaconChannelSet;
Shaun Nelson 38:182ba91524e4 337 rxBeaconSetup.CustomFrequency = BeaconCtx.Frequency;
Shaun Nelson 38:182ba91524e4 338 rxBeaconSetup.BeaconTime = BeaconCtx.BeaconTime;
Shaun Nelson 38:182ba91524e4 339 rxBeaconSetup.BeaconInterval = BeaconCtx.Cfg.Interval;
Shaun Nelson 38:182ba91524e4 340
Shaun Nelson 38:182ba91524e4 341 RegionRxBeaconSetup( *LoRaMacClassBParams.LoRaMacRegion, &rxBeaconSetup, &LoRaMacClassBParams.McpsIndication->RxDatarate, &beaconChannelSet );
Shaun Nelson 38:182ba91524e4 342 BeaconCtx.Ctrl.BeaconChannelSet = beaconChannelSet;
Shaun Nelson 48:81c0f4c4dd2c 343 BeaconCtx.BeaconAcqTime = 0;
Shaun Nelson 38:182ba91524e4 344 }
Shaun Nelson 38:182ba91524e4 345 BeaconCtx.NextBeaconRx = 0;
Shaun Nelson 38:182ba91524e4 346 BeaconCtx.BeaconTimingDelay = 0;
Shaun Nelson 48:81c0f4c4dd2c 347 BeaconCtx.BeaconTimingAnsTime = 0;
Shaun Nelson 38:182ba91524e4 348 }
Shaun Nelson 38:182ba91524e4 349 else
Shaun Nelson 38:182ba91524e4 350 {
Shaun Nelson 38:182ba91524e4 351 BeaconCtx.Ctrl.BeaconDelaySet = 0;
Shaun Nelson 38:182ba91524e4 352 BeaconCtx.Ctrl.AcquisitionPending = 0;
Shaun Nelson 38:182ba91524e4 353 BeaconCtx.Ctrl.AcquisitionTimerSet = 1;
Shaun Nelson 38:182ba91524e4 354 beaconEventTime = BeaconCtx.Cfg.DelayBeaconTimingAns;
Shaun Nelson 38:182ba91524e4 355
Shaun Nelson 38:182ba91524e4 356 rxBeaconSetup.SymbolTimeout = BeaconCtx.SymbolTimeout;
Shaun Nelson 38:182ba91524e4 357 rxBeaconSetup.RxTime = 0;
Shaun Nelson 38:182ba91524e4 358 rxBeaconSetup.DeviceAddress = *LoRaMacClassBParams.LoRaMacDevAddr;
Shaun Nelson 38:182ba91524e4 359 rxBeaconSetup.BeaconTimingChannel = BeaconCtx.BeaconTimingChannel;
Shaun Nelson 38:182ba91524e4 360 rxBeaconSetup.CustomFrequencyEnabled = BeaconCtx.Ctrl.CustomFreq;
Shaun Nelson 38:182ba91524e4 361 rxBeaconSetup.BeaconChannelSet = BeaconCtx.Ctrl.BeaconChannelSet;
Shaun Nelson 38:182ba91524e4 362 rxBeaconSetup.CustomFrequency = BeaconCtx.Frequency;
Shaun Nelson 38:182ba91524e4 363 rxBeaconSetup.BeaconTime = BeaconCtx.BeaconTime;
Shaun Nelson 38:182ba91524e4 364 rxBeaconSetup.BeaconInterval = BeaconCtx.Cfg.Interval;
Shaun Nelson 48:81c0f4c4dd2c 365 BeaconCtx.BeaconAcqTime = 0;
Shaun Nelson 38:182ba91524e4 366
Shaun Nelson 38:182ba91524e4 367 RegionRxBeaconSetup( *LoRaMacClassBParams.LoRaMacRegion, &rxBeaconSetup, &LoRaMacClassBParams.McpsIndication->RxDatarate, &beaconChannelSet );
Shaun Nelson 38:182ba91524e4 368 BeaconCtx.Ctrl.BeaconChannelSet = beaconChannelSet;
Shaun Nelson 38:182ba91524e4 369 }
Shaun Nelson 38:182ba91524e4 370 }
Shaun Nelson 38:182ba91524e4 371 else
Shaun Nelson 38:182ba91524e4 372 {
Shaun Nelson 38:182ba91524e4 373 BeaconCtx.Ctrl.AcquisitionPending = 1;
Shaun Nelson 48:81c0f4c4dd2c 374 // SKN - Closing Beacon Rx window after 10 seconds instead of miss and wait of 128 seconds
Shaun Nelson 48:81c0f4c4dd2c 375 beaconEventTime = 10000;
Shaun Nelson 48:81c0f4c4dd2c 376 // beaconEventTime = BeaconCtx.Cfg.Interval;
Shaun Nelson 38:182ba91524e4 377 if( BeaconCtx.Ctrl.AcquisitionTimerSet == 0 )
Shaun Nelson 38:182ba91524e4 378 {
Shaun Nelson 38:182ba91524e4 379 rxBeaconSetup.SymbolTimeout = BeaconCtx.SymbolTimeout;
Shaun Nelson 38:182ba91524e4 380 rxBeaconSetup.RxTime = 0;
Shaun Nelson 38:182ba91524e4 381 rxBeaconSetup.DeviceAddress = *LoRaMacClassBParams.LoRaMacDevAddr;
Shaun Nelson 38:182ba91524e4 382 rxBeaconSetup.BeaconTimingChannel = BeaconCtx.BeaconTimingChannel;
Shaun Nelson 38:182ba91524e4 383 rxBeaconSetup.CustomFrequencyEnabled = BeaconCtx.Ctrl.CustomFreq;
Shaun Nelson 38:182ba91524e4 384 rxBeaconSetup.BeaconChannelSet = BeaconCtx.Ctrl.BeaconChannelSet;
Shaun Nelson 38:182ba91524e4 385 rxBeaconSetup.CustomFrequency = BeaconCtx.Frequency;
Shaun Nelson 38:182ba91524e4 386 rxBeaconSetup.BeaconTime = BeaconCtx.BeaconTime;
Shaun Nelson 38:182ba91524e4 387 rxBeaconSetup.BeaconInterval = BeaconCtx.Cfg.Interval;
Shaun Nelson 48:81c0f4c4dd2c 388 BeaconCtx.BeaconAcqTime = 0;
Shaun Nelson 38:182ba91524e4 389
Shaun Nelson 38:182ba91524e4 390 RegionRxBeaconSetup( *LoRaMacClassBParams.LoRaMacRegion, &rxBeaconSetup, &LoRaMacClassBParams.McpsIndication->RxDatarate, &beaconChannelSet );
Shaun Nelson 38:182ba91524e4 391 BeaconCtx.Ctrl.BeaconChannelSet = beaconChannelSet;
Shaun Nelson 38:182ba91524e4 392 }
Shaun Nelson 38:182ba91524e4 393 BeaconCtx.Ctrl.AcquisitionTimerSet = 0;
Shaun Nelson 38:182ba91524e4 394 }
Shaun Nelson 38:182ba91524e4 395 }
Shaun Nelson 38:182ba91524e4 396 break;
Shaun Nelson 38:182ba91524e4 397 }
Shaun Nelson 38:182ba91524e4 398 case BEACON_STATE_TIMEOUT:
Shaun Nelson 38:182ba91524e4 399 {
Shaun Nelson 38:182ba91524e4 400 // Store listen time
Shaun Nelson 38:182ba91524e4 401 BeaconCtx.ListenTime = currentTime - BeaconCtx.NextBeaconRx;
Shaun Nelson 38:182ba91524e4 402 // Setup next state
Shaun Nelson 38:182ba91524e4 403 BeaconState = BEACON_STATE_BEACON_MISSED;
Shaun Nelson 38:182ba91524e4 404 // no break here
Shaun Nelson 38:182ba91524e4 405 }
Shaun Nelson 38:182ba91524e4 406 case BEACON_STATE_BEACON_MISSED:
Shaun Nelson 38:182ba91524e4 407 {
Shaun Nelson 38:182ba91524e4 408 // We have to update the beacon time, since we missed a beacon
Shaun Nelson 38:182ba91524e4 409 BeaconCtx.BeaconTime += ( BeaconCtx.Cfg.Interval / 1000 );
Shaun Nelson 38:182ba91524e4 410
Shaun Nelson 38:182ba91524e4 411 // Update symbol timeout
Shaun Nelson 38:182ba91524e4 412 BeaconCtx.SymbolTimeout *= BeaconCtx.Cfg.SymbolToExpansionFactor;
Shaun Nelson 38:182ba91524e4 413 if( BeaconCtx.SymbolTimeout > BeaconCtx.Cfg.SymbolToExpansionMax )
Shaun Nelson 38:182ba91524e4 414 {
Shaun Nelson 38:182ba91524e4 415 BeaconCtx.SymbolTimeout = BeaconCtx.Cfg.SymbolToExpansionMax;
Shaun Nelson 38:182ba91524e4 416 }
Shaun Nelson 38:182ba91524e4 417 PingSlotCtx.SymbolTimeout *= PingSlotCtx.Cfg.SymbolToExpansionFactor;
Shaun Nelson 38:182ba91524e4 418 if( PingSlotCtx.SymbolTimeout > PingSlotCtx.Cfg.SymbolToExpansionMax )
Shaun Nelson 38:182ba91524e4 419 {
Shaun Nelson 38:182ba91524e4 420 PingSlotCtx.SymbolTimeout = PingSlotCtx.Cfg.SymbolToExpansionMax;
Shaun Nelson 38:182ba91524e4 421 }
Shaun Nelson 38:182ba91524e4 422 // Setup next state
Shaun Nelson 38:182ba91524e4 423 BeaconState = BEACON_STATE_REACQUISITION;
Shaun Nelson 38:182ba91524e4 424 // no break here
Shaun Nelson 38:182ba91524e4 425 }
Shaun Nelson 38:182ba91524e4 426 case BEACON_STATE_REACQUISITION:
Shaun Nelson 38:182ba91524e4 427 {
Shaun Nelson 38:182ba91524e4 428 if( ( currentTime - BeaconCtx.LastBeaconRx ) > BeaconCtx.Cfg.MaxBeaconLessPeriod )
Shaun Nelson 38:182ba91524e4 429 {
Shaun Nelson 38:182ba91524e4 430 activateTimer = true;
Shaun Nelson 38:182ba91524e4 431 BeaconState = BEACON_STATE_SWITCH_CLASS;
Shaun Nelson 38:182ba91524e4 432 }
Shaun Nelson 38:182ba91524e4 433 else
Shaun Nelson 38:182ba91524e4 434 {
Shaun Nelson 38:182ba91524e4 435 activateTimer = true;
Shaun Nelson 38:182ba91524e4 436 // Calculate the point in time of the next beacon
Shaun Nelson 38:182ba91524e4 437 beaconEventTime = ( ( currentTime - BeaconCtx.LastBeaconRx ) % BeaconCtx.Cfg.Interval );
Shaun Nelson 38:182ba91524e4 438 beaconEventTime = BeaconCtx.Cfg.Interval - beaconEventTime;
Shaun Nelson 38:182ba91524e4 439 // Take window enlargement into account
Shaun Nelson 38:182ba91524e4 440 beaconEventTime -= ( ( BeaconCtx.ListenTime * BeaconCtx.Cfg.SymbolToExpansionFactor ) >> 1 );
Shaun Nelson 38:182ba91524e4 441 beaconEventTime = TimerTempCompensation( beaconEventTime, BeaconCtx.Temperature );
Shaun Nelson 38:182ba91524e4 442 BeaconCtx.NextBeaconRx = currentTime + beaconEventTime;
Shaun Nelson 38:182ba91524e4 443
Shaun Nelson 38:182ba91524e4 444 // Make sure to transit to the correct state
Shaun Nelson 38:182ba91524e4 445 if( ( currentTime + BeaconCtx.Cfg.Guard ) < BeaconCtx.NextBeaconRx )
Shaun Nelson 38:182ba91524e4 446 {
Shaun Nelson 38:182ba91524e4 447 beaconEventTime -= BeaconCtx.Cfg.Guard;
Shaun Nelson 38:182ba91524e4 448 BeaconState = BEACON_STATE_IDLE;
Shaun Nelson 38:182ba91524e4 449 }
Shaun Nelson 38:182ba91524e4 450 else
Shaun Nelson 38:182ba91524e4 451 {
Shaun Nelson 38:182ba91524e4 452 BeaconState = BEACON_STATE_GUARD;
Shaun Nelson 38:182ba91524e4 453 }
Shaun Nelson 38:182ba91524e4 454
Shaun Nelson 38:182ba91524e4 455 if( PingSlotCtx.Ctrl.Assigned == 1 )
Shaun Nelson 38:182ba91524e4 456 {
Shaun Nelson 38:182ba91524e4 457 PingSlotState = PINGSLOT_STATE_CALC_PING_OFFSET;
Shaun Nelson 38:182ba91524e4 458 TimerSetValue( &PingSlotTimer, 1 );
Shaun Nelson 38:182ba91524e4 459 TimerStart( &PingSlotTimer );
Shaun Nelson 38:182ba91524e4 460
Shaun Nelson 38:182ba91524e4 461 MulticastSlotState = PINGSLOT_STATE_CALC_PING_OFFSET;
Shaun Nelson 38:182ba91524e4 462 TimerSetValue( &MulticastSlotTimer, 1 );
Shaun Nelson 38:182ba91524e4 463 TimerStart( &MulticastSlotTimer );
Shaun Nelson 38:182ba91524e4 464 }
Shaun Nelson 38:182ba91524e4 465 }
Shaun Nelson 38:182ba91524e4 466 BeaconCtx.Ctrl.BeaconAcquired = 0;
Shaun Nelson 38:182ba91524e4 467
Shaun Nelson 38:182ba91524e4 468 if( BeaconCtx.Ctrl.ResumeBeaconing == 0 )
Shaun Nelson 38:182ba91524e4 469 {
Shaun Nelson 38:182ba91524e4 470 LoRaMacClassBParams.MlmeIndication->MlmeIndication = MLME_BEACON;
Shaun Nelson 38:182ba91524e4 471 LoRaMacClassBParams.MlmeIndication->Status = LORAMAC_EVENT_INFO_STATUS_BEACON_LOST;
Shaun Nelson 38:182ba91524e4 472 LoRaMacClassBParams.LoRaMacFlags->Bits.MlmeInd = 1;
Shaun Nelson 38:182ba91524e4 473
Shaun Nelson 38:182ba91524e4 474 TimerSetValue( LoRaMacClassBParams.MacStateCheckTimer, 1 );
Shaun Nelson 38:182ba91524e4 475 TimerStart( LoRaMacClassBParams.MacStateCheckTimer );
Shaun Nelson 38:182ba91524e4 476 LoRaMacClassBParams.LoRaMacFlags->Bits.MacDone = 1;
Shaun Nelson 38:182ba91524e4 477 }
Shaun Nelson 38:182ba91524e4 478 BeaconCtx.Ctrl.ResumeBeaconing = 0;
Shaun Nelson 38:182ba91524e4 479 break;
Shaun Nelson 38:182ba91524e4 480 }
Shaun Nelson 38:182ba91524e4 481 case BEACON_STATE_LOCKED:
Shaun Nelson 38:182ba91524e4 482 {
Shaun Nelson 38:182ba91524e4 483 activateTimer = true;
Shaun Nelson 38:182ba91524e4 484 // Calculate the point in time of the next beacon
Shaun Nelson 38:182ba91524e4 485 beaconEventTime = ( ( currentTime - BeaconCtx.LastBeaconRx ) % BeaconCtx.Cfg.Interval );
Shaun Nelson 38:182ba91524e4 486 beaconEventTime = BeaconCtx.Cfg.Interval - beaconEventTime;
Shaun Nelson 38:182ba91524e4 487 beaconEventTime = TimerTempCompensation( beaconEventTime, BeaconCtx.Temperature );
Shaun Nelson 38:182ba91524e4 488 BeaconCtx.NextBeaconRx = currentTime + beaconEventTime;
Shaun Nelson 38:182ba91524e4 489
Shaun Nelson 38:182ba91524e4 490 // Make sure to transit to the correct state
Shaun Nelson 38:182ba91524e4 491 if( ( currentTime + BeaconCtx.Cfg.Guard ) < BeaconCtx.NextBeaconRx )
Shaun Nelson 38:182ba91524e4 492 {
Shaun Nelson 38:182ba91524e4 493 beaconEventTime -= BeaconCtx.Cfg.Guard;
Shaun Nelson 38:182ba91524e4 494 BeaconState = BEACON_STATE_IDLE;
Shaun Nelson 38:182ba91524e4 495 }
Shaun Nelson 38:182ba91524e4 496 else
Shaun Nelson 38:182ba91524e4 497 {
Shaun Nelson 38:182ba91524e4 498 BeaconState = BEACON_STATE_GUARD;
Shaun Nelson 38:182ba91524e4 499 }
Shaun Nelson 38:182ba91524e4 500
Shaun Nelson 38:182ba91524e4 501 if( LoRaMacClassBParams.LoRaMacFlags->Bits.MlmeReq == 1 )
Shaun Nelson 38:182ba91524e4 502 {
Shaun Nelson 38:182ba91524e4 503 // index = GetMlmeConfirmIndex( MlmeConfirmQueue, MLME_BEACON_ACQUISITION, MlmeConfirmQueueCnt );
Shaun Nelson 38:182ba91524e4 504 index = LoRaMacClassBCallbacks.GetMlmeConfrimIndex( LoRaMacClassBParams.MlmeConfirmQueue, MLME_BEACON_ACQUISITION );
Shaun Nelson 38:182ba91524e4 505 if( index < LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
Shaun Nelson 38:182ba91524e4 506 {
Shaun Nelson 38:182ba91524e4 507 LoRaMacClassBParams.MlmeConfirmQueue[index].Status = LORAMAC_EVENT_INFO_STATUS_OK;
Shaun Nelson 38:182ba91524e4 508 LoRaMacClassBParams.MlmeConfirm->TxTimeOnAir = 0;
Shaun Nelson 38:182ba91524e4 509 }
Shaun Nelson 38:182ba91524e4 510 }
Shaun Nelson 38:182ba91524e4 511
Shaun Nelson 38:182ba91524e4 512 if( PingSlotCtx.Ctrl.Assigned == 1 )
Shaun Nelson 38:182ba91524e4 513 {
Shaun Nelson 38:182ba91524e4 514 PingSlotState = PINGSLOT_STATE_CALC_PING_OFFSET;
Shaun Nelson 38:182ba91524e4 515 TimerSetValue( &PingSlotTimer, 1 );
Shaun Nelson 38:182ba91524e4 516 TimerStart( &PingSlotTimer );
Shaun Nelson 38:182ba91524e4 517
Shaun Nelson 38:182ba91524e4 518 MulticastSlotState = PINGSLOT_STATE_CALC_PING_OFFSET;
Shaun Nelson 38:182ba91524e4 519 TimerSetValue( &MulticastSlotTimer, 1 );
Shaun Nelson 38:182ba91524e4 520 TimerStart( &MulticastSlotTimer );
Shaun Nelson 38:182ba91524e4 521 }
Shaun Nelson 38:182ba91524e4 522 BeaconCtx.Ctrl.AcquisitionPending = 0;
Shaun Nelson 38:182ba91524e4 523
Shaun Nelson 38:182ba91524e4 524 if( BeaconCtx.Ctrl.ResumeBeaconing == 0 )
Shaun Nelson 38:182ba91524e4 525 {
Shaun Nelson 38:182ba91524e4 526 LoRaMacClassBParams.MlmeIndication->MlmeIndication = MLME_BEACON;
Shaun Nelson 38:182ba91524e4 527 LoRaMacClassBParams.MlmeIndication->Status = LORAMAC_EVENT_INFO_STATUS_BEACON_LOCKED;
Shaun Nelson 38:182ba91524e4 528 LoRaMacClassBParams.LoRaMacFlags->Bits.MlmeInd = 1;
Shaun Nelson 38:182ba91524e4 529
Shaun Nelson 38:182ba91524e4 530 TimerSetValue( LoRaMacClassBParams.MacStateCheckTimer, 1 );
Shaun Nelson 38:182ba91524e4 531 TimerStart( LoRaMacClassBParams.MacStateCheckTimer );
Shaun Nelson 38:182ba91524e4 532 LoRaMacClassBParams.LoRaMacFlags->Bits.MacDone = 1;
Shaun Nelson 38:182ba91524e4 533 }
Shaun Nelson 38:182ba91524e4 534 BeaconCtx.Ctrl.ResumeBeaconing = 0;
Shaun Nelson 48:81c0f4c4dd2c 535
Shaun Nelson 38:182ba91524e4 536 break;
Shaun Nelson 38:182ba91524e4 537 }
Shaun Nelson 38:182ba91524e4 538 case BEACON_STATE_IDLE:
Shaun Nelson 38:182ba91524e4 539 {
Shaun Nelson 38:182ba91524e4 540 activateTimer = true;
Shaun Nelson 38:182ba91524e4 541 GetTemperatureLevel( &LoRaMacClassBCallbacks, &BeaconCtx );
Shaun Nelson 38:182ba91524e4 542 beaconEventTime = BeaconCtx.NextBeaconRx - RADIO_WAKEUP_TIME;
Shaun Nelson 38:182ba91524e4 543 currentTime = TimerGetCurrentTime( );
Shaun Nelson 38:182ba91524e4 544
Shaun Nelson 38:182ba91524e4 545 if( beaconEventTime > currentTime )
Shaun Nelson 38:182ba91524e4 546 {
Shaun Nelson 38:182ba91524e4 547 BeaconState = BEACON_STATE_GUARD;
Shaun Nelson 38:182ba91524e4 548 beaconEventTime -= currentTime;
Shaun Nelson 38:182ba91524e4 549 beaconEventTime = TimerTempCompensation( beaconEventTime, BeaconCtx.Temperature );
Shaun Nelson 38:182ba91524e4 550 }
Shaun Nelson 38:182ba91524e4 551 else
Shaun Nelson 38:182ba91524e4 552 {
Shaun Nelson 38:182ba91524e4 553 BeaconState = BEACON_STATE_REACQUISITION;
Shaun Nelson 38:182ba91524e4 554 beaconEventTime = 1;
Shaun Nelson 38:182ba91524e4 555 }
Shaun Nelson 38:182ba91524e4 556 break;
Shaun Nelson 38:182ba91524e4 557 }
Shaun Nelson 38:182ba91524e4 558 case BEACON_STATE_GUARD:
Shaun Nelson 38:182ba91524e4 559 {
Shaun Nelson 38:182ba91524e4 560 BeaconState = BEACON_STATE_RX;
Shaun Nelson 38:182ba91524e4 561
Shaun Nelson 38:182ba91524e4 562 rxBeaconSetup.SymbolTimeout = BeaconCtx.SymbolTimeout;
Shaun Nelson 38:182ba91524e4 563 rxBeaconSetup.RxTime = BeaconCtx.Cfg.Reserved;
Shaun Nelson 38:182ba91524e4 564 rxBeaconSetup.DeviceAddress = *LoRaMacClassBParams.LoRaMacDevAddr;
Shaun Nelson 38:182ba91524e4 565 rxBeaconSetup.BeaconTimingChannel = BeaconCtx.BeaconTimingChannel;
Shaun Nelson 38:182ba91524e4 566 rxBeaconSetup.CustomFrequencyEnabled = BeaconCtx.Ctrl.CustomFreq;
Shaun Nelson 38:182ba91524e4 567 rxBeaconSetup.BeaconChannelSet = BeaconCtx.Ctrl.BeaconChannelSet;
Shaun Nelson 38:182ba91524e4 568 rxBeaconSetup.CustomFrequency = BeaconCtx.Frequency;
Shaun Nelson 38:182ba91524e4 569 rxBeaconSetup.BeaconTime = BeaconCtx.BeaconTime;
Shaun Nelson 38:182ba91524e4 570 rxBeaconSetup.BeaconInterval = BeaconCtx.Cfg.Interval;
Shaun Nelson 38:182ba91524e4 571
Shaun Nelson 38:182ba91524e4 572 RegionRxBeaconSetup( *LoRaMacClassBParams.LoRaMacRegion, &rxBeaconSetup, &LoRaMacClassBParams.McpsIndication->RxDatarate, &beaconChannelSet );
Shaun Nelson 38:182ba91524e4 573 BeaconCtx.Ctrl.BeaconChannelSet = beaconChannelSet;
Shaun Nelson 38:182ba91524e4 574 break;
Shaun Nelson 38:182ba91524e4 575 }
Shaun Nelson 38:182ba91524e4 576 case BEACON_STATE_SWITCH_CLASS:
Shaun Nelson 38:182ba91524e4 577 {
Shaun Nelson 38:182ba91524e4 578 if( LoRaMacClassBParams.LoRaMacFlags->Bits.MlmeReq == 1 )
Shaun Nelson 38:182ba91524e4 579 {
Shaun Nelson 38:182ba91524e4 580 // index = GetMlmeConfirmIndex( MlmeConfirmQueue, MLME_BEACON_ACQUISITION, MlmeConfirmQueueCnt );
Shaun Nelson 38:182ba91524e4 581 index = LoRaMacClassBCallbacks.GetMlmeConfrimIndex( LoRaMacClassBParams.MlmeConfirmQueue, MLME_BEACON_ACQUISITION );
Shaun Nelson 38:182ba91524e4 582 if( index < LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
Shaun Nelson 38:182ba91524e4 583 {
Shaun Nelson 38:182ba91524e4 584 LoRaMacClassBParams.MlmeConfirmQueue[index].Status = LORAMAC_EVENT_INFO_STATUS_BEACON_NOT_FOUND;
Shaun Nelson 38:182ba91524e4 585 }
Shaun Nelson 38:182ba91524e4 586 }
Shaun Nelson 38:182ba91524e4 587 else
Shaun Nelson 38:182ba91524e4 588 {
Shaun Nelson 38:182ba91524e4 589 LoRaMacClassBParams.MlmeIndication->MlmeIndication = MLME_SWITCH_CLASS;
Shaun Nelson 38:182ba91524e4 590 LoRaMacClassBParams.MlmeIndication->Status = LORAMAC_EVENT_INFO_STATUS_OK;
Shaun Nelson 38:182ba91524e4 591 PingSlotCtx.Ctrl.Assigned = 0;
Shaun Nelson 38:182ba91524e4 592 LoRaMacClassBParams.LoRaMacFlags->Bits.MlmeInd = 1;
Shaun Nelson 38:182ba91524e4 593 }
Shaun Nelson 38:182ba91524e4 594 BeaconState = BEACON_STATE_ACQUISITION;
Shaun Nelson 38:182ba91524e4 595
Shaun Nelson 38:182ba91524e4 596 BeaconCtx.Ctrl.BeaconMode = 0;
Shaun Nelson 38:182ba91524e4 597 BeaconCtx.Ctrl.AcquisitionPending = 0;
Shaun Nelson 38:182ba91524e4 598 BeaconCtx.Ctrl.AcquisitionTimerSet = 0;
Shaun Nelson 38:182ba91524e4 599 LoRaMacClassBParams.LoRaMacFlags->Bits.MacDone = 1;
Shaun Nelson 38:182ba91524e4 600
Shaun Nelson 38:182ba91524e4 601 TimerSetValue( LoRaMacClassBParams.MacStateCheckTimer, beaconEventTime );
Shaun Nelson 38:182ba91524e4 602 TimerStart( LoRaMacClassBParams.MacStateCheckTimer );
Shaun Nelson 38:182ba91524e4 603 break;
Shaun Nelson 38:182ba91524e4 604 }
Shaun Nelson 38:182ba91524e4 605 default:
Shaun Nelson 38:182ba91524e4 606 {
Shaun Nelson 38:182ba91524e4 607 BeaconState = BEACON_STATE_ACQUISITION;
Shaun Nelson 38:182ba91524e4 608 break;
Shaun Nelson 38:182ba91524e4 609 }
Shaun Nelson 38:182ba91524e4 610 }
Shaun Nelson 38:182ba91524e4 611
Shaun Nelson 38:182ba91524e4 612 if( activateTimer == true )
Shaun Nelson 38:182ba91524e4 613 {
Shaun Nelson 40:f7ce84dc9363 614 BeaconEventTime = beaconEventTime;
Shaun Nelson 40:f7ce84dc9363 615
Shaun Nelson 38:182ba91524e4 616 TimerSetValue( &BeaconTimer, beaconEventTime );
Shaun Nelson 38:182ba91524e4 617 TimerStart( &BeaconTimer );
Shaun Nelson 38:182ba91524e4 618 }
Shaun Nelson 40:f7ce84dc9363 619 else
Shaun Nelson 40:f7ce84dc9363 620 BeaconEventTime = 0;
Shaun Nelson 40:f7ce84dc9363 621
Shaun Nelson 38:182ba91524e4 622 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 623 }
Shaun Nelson 38:182ba91524e4 624
Shaun Nelson 38:182ba91524e4 625 void LoRaMacClassBPingSlotTimerEvent( void )
Shaun Nelson 38:182ba91524e4 626 {
Shaun Nelson 38:182ba91524e4 627 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 628 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 629 PhyParam_t phyParam;
Shaun Nelson 38:182ba91524e4 630 RxConfigParams_t pingSlotRxConfig;
Shaun Nelson 38:182ba91524e4 631 TimerTime_t pingSlotTime = 0;
Shaun Nelson 38:182ba91524e4 632
Shaun Nelson 38:182ba91524e4 633 TimerStop( &PingSlotTimer );
Shaun Nelson 38:182ba91524e4 634
Shaun Nelson 38:182ba91524e4 635 switch( PingSlotState )
Shaun Nelson 38:182ba91524e4 636 {
Shaun Nelson 38:182ba91524e4 637 case PINGSLOT_STATE_CALC_PING_OFFSET:
Shaun Nelson 38:182ba91524e4 638 {
Shaun Nelson 38:182ba91524e4 639 LoRaMacBeaconComputePingOffset( BeaconCtx.BeaconTime,
Shaun Nelson 38:182ba91524e4 640 *LoRaMacClassBParams.LoRaMacDevAddr,
Shaun Nelson 38:182ba91524e4 641 PingSlotCtx.PingPeriod,
Shaun Nelson 38:182ba91524e4 642 &( PingSlotCtx.PingOffset ) );
Shaun Nelson 38:182ba91524e4 643 PingSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 644 // no break
Shaun Nelson 38:182ba91524e4 645 }
Shaun Nelson 38:182ba91524e4 646 case PINGSLOT_STATE_SET_TIMER:
Shaun Nelson 38:182ba91524e4 647 {
Shaun Nelson 38:182ba91524e4 648 if( CalcNextSlotTime( PingSlotCtx.PingOffset, PingSlotCtx.PingPeriod, &pingSlotTime ) == true )
Shaun Nelson 38:182ba91524e4 649 {
Shaun Nelson 38:182ba91524e4 650 // Start the timer if the ping slot time is in range
Shaun Nelson 38:182ba91524e4 651 PingSlotState = PINGSLOT_STATE_IDLE;
Shaun Nelson 38:182ba91524e4 652 TimerSetValue( &PingSlotTimer, pingSlotTime );
Shaun Nelson 38:182ba91524e4 653 TimerStart( &PingSlotTimer );
Shaun Nelson 38:182ba91524e4 654 }
Shaun Nelson 38:182ba91524e4 655 break;
Shaun Nelson 38:182ba91524e4 656 }
Shaun Nelson 38:182ba91524e4 657 case PINGSLOT_STATE_IDLE:
Shaun Nelson 38:182ba91524e4 658 {
Shaun Nelson 38:182ba91524e4 659 uint32_t frequency = PingSlotCtx.Frequency;
Shaun Nelson 38:182ba91524e4 660
Shaun Nelson 38:182ba91524e4 661 if( PingSlotCtx.Ctrl.CustomFreq == 0 )
Shaun Nelson 38:182ba91524e4 662 {
Shaun Nelson 38:182ba91524e4 663 // Restore floor plan
Shaun Nelson 38:182ba91524e4 664 getPhy.Attribute = PHY_PINGSLOT_CHANNEL_FREQ;
Shaun Nelson 38:182ba91524e4 665 getPhy.DeviceAddress = *LoRaMacClassBParams.LoRaMacDevAddr;
Shaun Nelson 48:81c0f4c4dd2c 666 getPhy.BeaconTime = BeaconCtx.BeaconTime;
Shaun Nelson 38:182ba91524e4 667 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 668 frequency = phyParam.Value;
Shaun Nelson 38:182ba91524e4 669 }
Shaun Nelson 38:182ba91524e4 670
Shaun Nelson 38:182ba91524e4 671 if( MulticastSlotState != PINGSLOT_STATE_RX )
Shaun Nelson 38:182ba91524e4 672 {
Shaun Nelson 38:182ba91524e4 673 if( BeaconCtx.Ctrl.BeaconAcquired == 1 )
Shaun Nelson 38:182ba91524e4 674 {
Shaun Nelson 38:182ba91524e4 675 RegionComputeRxWindowParameters( *LoRaMacClassBParams.LoRaMacRegion,
Shaun Nelson 38:182ba91524e4 676 PingSlotCtx.Datarate,
Shaun Nelson 38:182ba91524e4 677 LoRaMacClassBParams.LoRaMacParams->MinRxSymbols,
Shaun Nelson 38:182ba91524e4 678 LoRaMacClassBParams.LoRaMacParams->SystemMaxRxError,
Shaun Nelson 38:182ba91524e4 679 &pingSlotRxConfig );
Shaun Nelson 38:182ba91524e4 680 PingSlotCtx.SymbolTimeout = pingSlotRxConfig.WindowTimeout;
Shaun Nelson 38:182ba91524e4 681 }
Shaun Nelson 38:182ba91524e4 682 PingSlotState = PINGSLOT_STATE_RX;
Shaun Nelson 38:182ba91524e4 683
Shaun Nelson 38:182ba91524e4 684 pingSlotRxConfig.Datarate = PingSlotCtx.Datarate;
Shaun Nelson 38:182ba91524e4 685 pingSlotRxConfig.DownlinkDwellTime = LoRaMacClassBParams.LoRaMacParams->DownlinkDwellTime;
Shaun Nelson 38:182ba91524e4 686 pingSlotRxConfig.RepeaterSupport = LoRaMacClassBParams.LoRaMacParams->RepeaterSupport;
Shaun Nelson 38:182ba91524e4 687 pingSlotRxConfig.Frequency = frequency;
Shaun Nelson 38:182ba91524e4 688 pingSlotRxConfig.RxContinuous = false;
Shaun Nelson 38:182ba91524e4 689 pingSlotRxConfig.Window = 1;
Shaun Nelson 38:182ba91524e4 690
Shaun Nelson 38:182ba91524e4 691 RegionRxConfig( *LoRaMacClassBParams.LoRaMacRegion, &pingSlotRxConfig, ( int8_t* )&LoRaMacClassBParams.McpsIndication->RxDatarate );
Shaun Nelson 38:182ba91524e4 692
Shaun Nelson 38:182ba91524e4 693 if( pingSlotRxConfig.RxContinuous == false )
Shaun Nelson 38:182ba91524e4 694 {
Shaun Nelson 38:182ba91524e4 695 Radio.Rx( LoRaMacClassBParams.LoRaMacParams->MaxRxWindow );
Shaun Nelson 38:182ba91524e4 696 }
Shaun Nelson 38:182ba91524e4 697 else
Shaun Nelson 38:182ba91524e4 698 {
Shaun Nelson 38:182ba91524e4 699 Radio.Rx( 0 ); // Continuous mode
Shaun Nelson 38:182ba91524e4 700 }
Shaun Nelson 38:182ba91524e4 701 }
Shaun Nelson 38:182ba91524e4 702 else
Shaun Nelson 38:182ba91524e4 703 {
Shaun Nelson 38:182ba91524e4 704 // Multicast slots have priority. Skip Rx
Shaun Nelson 38:182ba91524e4 705 PingSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 706 TimerSetValue( &PingSlotTimer, PingSlotCtx.Cfg.PingSlotWindow );
Shaun Nelson 38:182ba91524e4 707 TimerStart( &PingSlotTimer );
Shaun Nelson 38:182ba91524e4 708 }
Shaun Nelson 38:182ba91524e4 709 break;
Shaun Nelson 38:182ba91524e4 710 }
Shaun Nelson 38:182ba91524e4 711 default:
Shaun Nelson 38:182ba91524e4 712 {
Shaun Nelson 38:182ba91524e4 713 PingSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 714 break;
Shaun Nelson 38:182ba91524e4 715 }
Shaun Nelson 38:182ba91524e4 716 }
Shaun Nelson 38:182ba91524e4 717 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 718 }
Shaun Nelson 38:182ba91524e4 719
Shaun Nelson 38:182ba91524e4 720 void LoRaMacClassBMulticastSlotTimerEvent( void )
Shaun Nelson 38:182ba91524e4 721 {
Shaun Nelson 38:182ba91524e4 722 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 723 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 724 PhyParam_t phyParam;
Shaun Nelson 38:182ba91524e4 725 RxConfigParams_t multicastSlotRxConfig;
Shaun Nelson 38:182ba91524e4 726 TimerTime_t multicastSlotTime = 0;
Shaun Nelson 38:182ba91524e4 727 TimerTime_t slotTime = 0;
Shaun Nelson 38:182ba91524e4 728 MulticastParams_t *cur = LoRaMacClassBParams.MulticastChannels;
Shaun Nelson 38:182ba91524e4 729
Shaun Nelson 38:182ba91524e4 730 TimerStop( &MulticastSlotTimer );
Shaun Nelson 38:182ba91524e4 731
Shaun Nelson 38:182ba91524e4 732 if( cur == NULL )
Shaun Nelson 38:182ba91524e4 733 {
Shaun Nelson 38:182ba91524e4 734 return;
Shaun Nelson 38:182ba91524e4 735 }
Shaun Nelson 38:182ba91524e4 736
Shaun Nelson 38:182ba91524e4 737 switch( MulticastSlotState )
Shaun Nelson 38:182ba91524e4 738 {
Shaun Nelson 38:182ba91524e4 739 case PINGSLOT_STATE_CALC_PING_OFFSET:
Shaun Nelson 38:182ba91524e4 740 {
Shaun Nelson 38:182ba91524e4 741 while( cur != NULL )
Shaun Nelson 38:182ba91524e4 742 {
Shaun Nelson 38:182ba91524e4 743 LoRaMacBeaconComputePingOffset( BeaconCtx.BeaconTime,
Shaun Nelson 38:182ba91524e4 744 cur->Address,
Shaun Nelson 38:182ba91524e4 745 PingSlotCtx.PingPeriod,
Shaun Nelson 38:182ba91524e4 746 &( cur->PingOffset ) );
Shaun Nelson 38:182ba91524e4 747 cur = cur->Next;
Shaun Nelson 38:182ba91524e4 748 }
Shaun Nelson 38:182ba91524e4 749 MulticastSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 750 // no break
Shaun Nelson 38:182ba91524e4 751 }
Shaun Nelson 38:182ba91524e4 752 case PINGSLOT_STATE_SET_TIMER:
Shaun Nelson 38:182ba91524e4 753 {
Shaun Nelson 38:182ba91524e4 754 cur = LoRaMacClassBParams.MulticastChannels;
Shaun Nelson 38:182ba91524e4 755 PingSlotCtx.NextMulticastChannel = NULL;
Shaun Nelson 38:182ba91524e4 756
Shaun Nelson 38:182ba91524e4 757 while( cur != NULL )
Shaun Nelson 38:182ba91524e4 758 {
Shaun Nelson 38:182ba91524e4 759 if( CalcNextSlotTime( cur->PingOffset, PingSlotCtx.PingPeriod, &slotTime ) == true )
Shaun Nelson 38:182ba91524e4 760 {
Shaun Nelson 38:182ba91524e4 761 if( ( multicastSlotTime == 0 ) || ( multicastSlotTime > slotTime ) )
Shaun Nelson 38:182ba91524e4 762 {
Shaun Nelson 38:182ba91524e4 763 // Update the slot time and the next multicast channel
Shaun Nelson 38:182ba91524e4 764 multicastSlotTime = slotTime;
Shaun Nelson 38:182ba91524e4 765 PingSlotCtx.NextMulticastChannel = cur;
Shaun Nelson 38:182ba91524e4 766 }
Shaun Nelson 38:182ba91524e4 767 }
Shaun Nelson 38:182ba91524e4 768 cur = cur->Next;
Shaun Nelson 38:182ba91524e4 769 }
Shaun Nelson 38:182ba91524e4 770
Shaun Nelson 38:182ba91524e4 771 if( PingSlotCtx.NextMulticastChannel != NULL )
Shaun Nelson 38:182ba91524e4 772 {
Shaun Nelson 38:182ba91524e4 773 // Start the timer if the ping slot time is in range
Shaun Nelson 38:182ba91524e4 774 MulticastSlotState = PINGSLOT_STATE_IDLE;
Shaun Nelson 38:182ba91524e4 775 TimerSetValue( &MulticastSlotTimer, multicastSlotTime );
Shaun Nelson 38:182ba91524e4 776 TimerStart( &MulticastSlotTimer );
Shaun Nelson 38:182ba91524e4 777 }
Shaun Nelson 38:182ba91524e4 778 break;
Shaun Nelson 38:182ba91524e4 779 }
Shaun Nelson 38:182ba91524e4 780 case PINGSLOT_STATE_IDLE:
Shaun Nelson 38:182ba91524e4 781 {
Shaun Nelson 38:182ba91524e4 782 uint32_t frequency = PingSlotCtx.Frequency;
Shaun Nelson 38:182ba91524e4 783
Shaun Nelson 38:182ba91524e4 784 if( PingSlotCtx.NextMulticastChannel == NULL )
Shaun Nelson 38:182ba91524e4 785 {
Shaun Nelson 38:182ba91524e4 786 MulticastSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 787 TimerSetValue( &MulticastSlotTimer, 1 );
Shaun Nelson 38:182ba91524e4 788 TimerStart( &MulticastSlotTimer );
Shaun Nelson 38:182ba91524e4 789 break;
Shaun Nelson 38:182ba91524e4 790 }
Shaun Nelson 38:182ba91524e4 791
Shaun Nelson 38:182ba91524e4 792 if( PingSlotCtx.Ctrl.CustomFreq == 0 )
Shaun Nelson 38:182ba91524e4 793 {
Shaun Nelson 38:182ba91524e4 794 // Restore floor plan
Shaun Nelson 38:182ba91524e4 795 getPhy.Attribute = PHY_PINGSLOT_CHANNEL_FREQ;
Shaun Nelson 38:182ba91524e4 796 getPhy.DeviceAddress = PingSlotCtx.NextMulticastChannel->Address;
Shaun Nelson 48:81c0f4c4dd2c 797 getPhy.BeaconTime = BeaconCtx.BeaconTime;
Shaun Nelson 48:81c0f4c4dd2c 798 //BeaconCtx.Cfg.Interval;
Shaun Nelson 38:182ba91524e4 799 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 800 frequency = phyParam.Value;
Shaun Nelson 38:182ba91524e4 801 }
Shaun Nelson 38:182ba91524e4 802
Shaun Nelson 38:182ba91524e4 803 if( BeaconCtx.Ctrl.BeaconAcquired == 1 )
Shaun Nelson 38:182ba91524e4 804 {
Shaun Nelson 38:182ba91524e4 805 RegionComputeRxWindowParameters( *LoRaMacClassBParams.LoRaMacRegion,
Shaun Nelson 38:182ba91524e4 806 PingSlotCtx.Datarate,
Shaun Nelson 38:182ba91524e4 807 LoRaMacClassBParams.LoRaMacParams->MinRxSymbols,
Shaun Nelson 38:182ba91524e4 808 LoRaMacClassBParams.LoRaMacParams->SystemMaxRxError,
Shaun Nelson 38:182ba91524e4 809 &multicastSlotRxConfig );
Shaun Nelson 38:182ba91524e4 810 PingSlotCtx.SymbolTimeout = multicastSlotRxConfig.WindowTimeout;
Shaun Nelson 38:182ba91524e4 811 }
Shaun Nelson 38:182ba91524e4 812 MulticastSlotState = PINGSLOT_STATE_RX;
Shaun Nelson 38:182ba91524e4 813
Shaun Nelson 38:182ba91524e4 814 multicastSlotRxConfig.Datarate = PingSlotCtx.Datarate;
Shaun Nelson 38:182ba91524e4 815 multicastSlotRxConfig.DownlinkDwellTime = LoRaMacClassBParams.LoRaMacParams->DownlinkDwellTime;
Shaun Nelson 38:182ba91524e4 816 multicastSlotRxConfig.RepeaterSupport = LoRaMacClassBParams.LoRaMacParams->RepeaterSupport;
Shaun Nelson 38:182ba91524e4 817 multicastSlotRxConfig.Frequency = frequency;
Shaun Nelson 38:182ba91524e4 818 multicastSlotRxConfig.RxContinuous = false;
Shaun Nelson 38:182ba91524e4 819 multicastSlotRxConfig.Window = 1;
Shaun Nelson 38:182ba91524e4 820
Shaun Nelson 38:182ba91524e4 821 RegionRxConfig( *LoRaMacClassBParams.LoRaMacRegion, &multicastSlotRxConfig, ( int8_t* )&LoRaMacClassBParams.McpsIndication->RxDatarate );
Shaun Nelson 38:182ba91524e4 822
Shaun Nelson 38:182ba91524e4 823 if( multicastSlotRxConfig.RxContinuous == false )
Shaun Nelson 38:182ba91524e4 824 {
Shaun Nelson 38:182ba91524e4 825 Radio.Rx( LoRaMacClassBParams.LoRaMacParams->MaxRxWindow );
Shaun Nelson 38:182ba91524e4 826 }
Shaun Nelson 38:182ba91524e4 827 else
Shaun Nelson 38:182ba91524e4 828 {
Shaun Nelson 38:182ba91524e4 829 Radio.Rx( 0 ); // Continuous mode
Shaun Nelson 38:182ba91524e4 830 }
Shaun Nelson 38:182ba91524e4 831 break;
Shaun Nelson 38:182ba91524e4 832 }
Shaun Nelson 38:182ba91524e4 833 default:
Shaun Nelson 38:182ba91524e4 834 {
Shaun Nelson 38:182ba91524e4 835 MulticastSlotState = PINGSLOT_STATE_SET_TIMER;
Shaun Nelson 38:182ba91524e4 836 break;
Shaun Nelson 38:182ba91524e4 837 }
Shaun Nelson 38:182ba91524e4 838 }
Shaun Nelson 38:182ba91524e4 839 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 840 }
Shaun Nelson 38:182ba91524e4 841
Shaun Nelson 48:81c0f4c4dd2c 842
Shaun Nelson 38:182ba91524e4 843 bool LoRaMacClassBRxBeacon( uint8_t *payload, uint16_t size )
Shaun Nelson 38:182ba91524e4 844 {
Shaun Nelson 38:182ba91524e4 845 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 846 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 847 PhyParam_t phyParam;
Shaun Nelson 38:182ba91524e4 848 bool beaconReceived = false;
Shaun Nelson 38:182ba91524e4 849 uint16_t crc0 = 0;
Shaun Nelson 38:182ba91524e4 850 uint16_t crc1 = 0;
Shaun Nelson 38:182ba91524e4 851 uint16_t beaconCrc0 = 0;
Shaun Nelson 38:182ba91524e4 852 uint16_t beaconCrc1 = 0;
Shaun Nelson 38:182ba91524e4 853 uint8_t rfuOffset1 = 0;
Shaun Nelson 38:182ba91524e4 854 uint8_t rfuOffset2 = 0;
Shaun Nelson 38:182ba91524e4 855
Shaun Nelson 38:182ba91524e4 856 getPhy.Attribute = PHY_BEACON_SIZE;
Shaun Nelson 38:182ba91524e4 857 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 858
Shaun Nelson 48:81c0f4c4dd2c 859 #define LORAWAN_ONE_ONE
Shaun Nelson 48:81c0f4c4dd2c 860 #ifdef LORAWAN_ONE_ONE
Shaun Nelson 48:81c0f4c4dd2c 861 rfuOffset1 = 3;
Shaun Nelson 48:81c0f4c4dd2c 862 rfuOffset2 = 3;
Shaun Nelson 48:81c0f4c4dd2c 863 #else
Shaun Nelson 38:182ba91524e4 864 // For beacon payload sizes > 17 we need to apply an offset
Shaun Nelson 38:182ba91524e4 865 if( phyParam.Value > 17 )
Shaun Nelson 38:182ba91524e4 866 {
Shaun Nelson 38:182ba91524e4 867 rfuOffset1 = 1;
Shaun Nelson 38:182ba91524e4 868 rfuOffset2 = 1;
Shaun Nelson 38:182ba91524e4 869 }
Shaun Nelson 48:81c0f4c4dd2c 870 #endif
Shaun Nelson 38:182ba91524e4 871
Shaun Nelson 38:182ba91524e4 872 // Verify if we are in the state where we expect a beacon
Shaun Nelson 38:182ba91524e4 873 if( ( BeaconState == BEACON_STATE_RX ) || ( BeaconCtx.Ctrl.AcquisitionPending == 1 ) )
Shaun Nelson 38:182ba91524e4 874 {
Shaun Nelson 48:81c0f4c4dd2c 875 if( size == phyParam.Value )
Shaun Nelson 38:182ba91524e4 876 {
Shaun Nelson 38:182ba91524e4 877 beaconCrc0 = ( ( uint16_t ) payload[6 + rfuOffset1] ) & 0x00FF;
Shaun Nelson 38:182ba91524e4 878 beaconCrc0 |= ( ( uint16_t ) payload[7 + rfuOffset1] << 8 ) & 0xFF00;
Shaun Nelson 38:182ba91524e4 879 crc0 = BeaconCrc( payload, 6 + rfuOffset1 );
Shaun Nelson 38:182ba91524e4 880
Shaun Nelson 38:182ba91524e4 881 // Validate the first crc of the beacon frame
Shaun Nelson 38:182ba91524e4 882 if( crc0 == beaconCrc0 )
Shaun Nelson 38:182ba91524e4 883 {
Shaun Nelson 38:182ba91524e4 884 BeaconCtx.BeaconTime = ( ( uint32_t ) payload[2 + rfuOffset1] ) & 0x000000FF;
Shaun Nelson 38:182ba91524e4 885 BeaconCtx.BeaconTime |= ( ( uint32_t ) ( payload[3 + rfuOffset1] << 8 ) ) & 0x0000FF00;
Shaun Nelson 38:182ba91524e4 886 BeaconCtx.BeaconTime |= ( ( uint32_t ) ( payload[4 + rfuOffset1] << 16 ) ) & 0x00FF0000;
Shaun Nelson 38:182ba91524e4 887 BeaconCtx.BeaconTime |= ( ( uint32_t ) ( payload[5 + rfuOffset1] << 24 ) ) & 0xFF000000;
Shaun Nelson 38:182ba91524e4 888 LoRaMacClassBParams.MlmeIndication->BeaconInfo.Time = BeaconCtx.BeaconTime;
Shaun Nelson 38:182ba91524e4 889 beaconReceived = true;
Shaun Nelson 38:182ba91524e4 890 }
Shaun Nelson 38:182ba91524e4 891
Shaun Nelson 38:182ba91524e4 892 beaconCrc1 = ( ( uint16_t ) payload[15 + rfuOffset1 + rfuOffset2] ) & 0x00FF;
Shaun Nelson 38:182ba91524e4 893 beaconCrc1 |= ( ( uint16_t ) payload[16 + rfuOffset1 + rfuOffset2] << 8 ) & 0xFF00;
Shaun Nelson 38:182ba91524e4 894 crc1 = BeaconCrc( &payload[8 + rfuOffset1], 7 + rfuOffset2 );
Shaun Nelson 38:182ba91524e4 895
Shaun Nelson 38:182ba91524e4 896 // Validate the second crc of the beacon frame
Shaun Nelson 38:182ba91524e4 897 if( crc1 == beaconCrc1 )
Shaun Nelson 38:182ba91524e4 898 {
Shaun Nelson 38:182ba91524e4 899 // Beacon valid, apply data
Shaun Nelson 38:182ba91524e4 900 LoRaMacClassBParams.MlmeIndication->BeaconInfo.GwSpecific.InfoDesc = payload[8 + rfuOffset1];
Shaun Nelson 38:182ba91524e4 901 memcpy1( LoRaMacClassBParams.MlmeIndication->BeaconInfo.GwSpecific.Info, &payload[9 + rfuOffset1], 7 );
Shaun Nelson 38:182ba91524e4 902 beaconReceived = true;
Shaun Nelson 38:182ba91524e4 903 }
Shaun Nelson 38:182ba91524e4 904
Shaun Nelson 38:182ba91524e4 905 // Reset beacon variables, if one of the crc is valid
Shaun Nelson 38:182ba91524e4 906 if( beaconReceived == true )
Shaun Nelson 38:182ba91524e4 907 {
Shaun Nelson 38:182ba91524e4 908 BeaconCtx.LastBeaconRx = TimerGetCurrentTime( ) - Radio.TimeOnAir( MODEM_LORA, size );
Shaun Nelson 38:182ba91524e4 909 BeaconCtx.Ctrl.BeaconAcquired = 1;
Shaun Nelson 38:182ba91524e4 910 BeaconCtx.Ctrl.BeaconMode = 1;
Shaun Nelson 38:182ba91524e4 911 BeaconCtx.SymbolTimeout = BeaconCtx.Cfg.SymbolToDefault;
Shaun Nelson 38:182ba91524e4 912 BeaconState = BEACON_STATE_LOCKED;
Shaun Nelson 38:182ba91524e4 913
Shaun Nelson 48:81c0f4c4dd2c 914 BeaconCtx.beaconLen = size;
Shaun Nelson 48:81c0f4c4dd2c 915 memcpy1( BeaconCtx.beaconPayload, payload, size );
Shaun Nelson 48:81c0f4c4dd2c 916
Shaun Nelson 38:182ba91524e4 917 LoRaMacClassBBeaconTimerEvent( );
Shaun Nelson 38:182ba91524e4 918 }
Shaun Nelson 40:f7ce84dc9363 919
Shaun Nelson 40:f7ce84dc9363 920 if( ( crc0 != beaconCrc0 ) || ( crc1 != beaconCrc1 ) )
Shaun Nelson 40:f7ce84dc9363 921 {
Shaun Nelson 40:f7ce84dc9363 922 BeaconCtx.BeaconRxError.count++;
Shaun Nelson 40:f7ce84dc9363 923 BeaconCtx.BeaconRxError.crc0 = beaconCrc0;
Shaun Nelson 40:f7ce84dc9363 924 BeaconCtx.BeaconRxError.calcCrc0 = crc0;
Shaun Nelson 40:f7ce84dc9363 925 BeaconCtx.BeaconRxError.crc1 = beaconCrc1;
Shaun Nelson 40:f7ce84dc9363 926 BeaconCtx.BeaconRxError.calcCrc1 = crc1;
Shaun Nelson 40:f7ce84dc9363 927 BeaconCtx.BeaconRxError.len = size;
Shaun Nelson 40:f7ce84dc9363 928
Shaun Nelson 40:f7ce84dc9363 929 uint8_t len = sizeof(BeaconCtx.BeaconRxError.payload);
Shaun Nelson 40:f7ce84dc9363 930 if( size < len )
Shaun Nelson 40:f7ce84dc9363 931 len = size;
Shaun Nelson 40:f7ce84dc9363 932
Shaun Nelson 40:f7ce84dc9363 933 memcpy1( BeaconCtx.BeaconRxError.payload, payload, len );
Shaun Nelson 40:f7ce84dc9363 934 BeaconCtx.BeaconRxError.len = len;
Shaun Nelson 40:f7ce84dc9363 935 }
Shaun Nelson 38:182ba91524e4 936 }
Shaun Nelson 38:182ba91524e4 937
Shaun Nelson 38:182ba91524e4 938 if( BeaconState == BEACON_STATE_RX )
Shaun Nelson 38:182ba91524e4 939 {
Shaun Nelson 38:182ba91524e4 940 BeaconState = BEACON_STATE_TIMEOUT;
Shaun Nelson 38:182ba91524e4 941 LoRaMacClassBBeaconTimerEvent( );
Shaun Nelson 38:182ba91524e4 942 }
Shaun Nelson 38:182ba91524e4 943 // Return always true, when we expect a beacon.
Shaun Nelson 38:182ba91524e4 944 beaconReceived = true;
Shaun Nelson 38:182ba91524e4 945 }
Shaun Nelson 38:182ba91524e4 946
Shaun Nelson 38:182ba91524e4 947 return beaconReceived;
Shaun Nelson 38:182ba91524e4 948 #else
Shaun Nelson 38:182ba91524e4 949 return false;
Shaun Nelson 38:182ba91524e4 950 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 951 }
Shaun Nelson 38:182ba91524e4 952
Shaun Nelson 38:182ba91524e4 953 bool LoRaMacClassBIsBeaconExpected( void )
Shaun Nelson 38:182ba91524e4 954 {
Shaun Nelson 38:182ba91524e4 955 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 956 if( ( BeaconCtx.Ctrl.AcquisitionPending == 1 ) ||
Shaun Nelson 38:182ba91524e4 957 ( BeaconCtx.Ctrl.AcquisitionTimerSet == 1 ) ||
Shaun Nelson 38:182ba91524e4 958 ( BeaconState == BEACON_STATE_RX ) )
Shaun Nelson 38:182ba91524e4 959 {
Shaun Nelson 38:182ba91524e4 960 return true;
Shaun Nelson 38:182ba91524e4 961 }
Shaun Nelson 38:182ba91524e4 962 return false;
Shaun Nelson 38:182ba91524e4 963 #else
Shaun Nelson 38:182ba91524e4 964 return false;
Shaun Nelson 38:182ba91524e4 965 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 966 }
Shaun Nelson 38:182ba91524e4 967
Shaun Nelson 38:182ba91524e4 968 bool LoRaMacClassBIsPingExpected( void )
Shaun Nelson 38:182ba91524e4 969 {
Shaun Nelson 38:182ba91524e4 970 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 971 if( PingSlotState == PINGSLOT_STATE_RX )
Shaun Nelson 38:182ba91524e4 972 {
Shaun Nelson 38:182ba91524e4 973 return true;
Shaun Nelson 38:182ba91524e4 974 }
Shaun Nelson 38:182ba91524e4 975 return false;
Shaun Nelson 38:182ba91524e4 976 #else
Shaun Nelson 38:182ba91524e4 977 return false;
Shaun Nelson 38:182ba91524e4 978 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 979 }
Shaun Nelson 38:182ba91524e4 980
Shaun Nelson 38:182ba91524e4 981 bool LoRaMacClassBIsAcquisitionPending( void )
Shaun Nelson 38:182ba91524e4 982 {
Shaun Nelson 38:182ba91524e4 983 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 984 if( BeaconCtx.Ctrl.AcquisitionPending == 1 )
Shaun Nelson 38:182ba91524e4 985 {
Shaun Nelson 38:182ba91524e4 986 return true;
Shaun Nelson 38:182ba91524e4 987 }
Shaun Nelson 38:182ba91524e4 988 return false;
Shaun Nelson 38:182ba91524e4 989 #else
Shaun Nelson 38:182ba91524e4 990 return false;
Shaun Nelson 38:182ba91524e4 991 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 992 }
Shaun Nelson 38:182ba91524e4 993
Shaun Nelson 38:182ba91524e4 994 bool LoRaMacClassBIsAcquisitionTimerSet( void )
Shaun Nelson 38:182ba91524e4 995 {
Shaun Nelson 38:182ba91524e4 996 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 997 if( BeaconCtx.Ctrl.AcquisitionTimerSet == 1 )
Shaun Nelson 38:182ba91524e4 998 {
Shaun Nelson 38:182ba91524e4 999 return true;
Shaun Nelson 38:182ba91524e4 1000 }
Shaun Nelson 38:182ba91524e4 1001 return false;
Shaun Nelson 38:182ba91524e4 1002 #else
Shaun Nelson 38:182ba91524e4 1003 return false;
Shaun Nelson 38:182ba91524e4 1004 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1005 }
Shaun Nelson 38:182ba91524e4 1006
Shaun Nelson 38:182ba91524e4 1007 bool LoRaMacClassBIsBeaconModeActive( void )
Shaun Nelson 38:182ba91524e4 1008 {
Shaun Nelson 38:182ba91524e4 1009 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1010 if( BeaconCtx.Ctrl.BeaconMode == 1 )
Shaun Nelson 38:182ba91524e4 1011 {
Shaun Nelson 38:182ba91524e4 1012 return true;
Shaun Nelson 38:182ba91524e4 1013 }
Shaun Nelson 38:182ba91524e4 1014 return false;
Shaun Nelson 38:182ba91524e4 1015 #else
Shaun Nelson 38:182ba91524e4 1016 return false;
Shaun Nelson 38:182ba91524e4 1017 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1018 }
Shaun Nelson 38:182ba91524e4 1019
Shaun Nelson 38:182ba91524e4 1020 void LoRaMacClassBSetPingSlotInfo( uint8_t periodicity )
Shaun Nelson 38:182ba91524e4 1021 {
Shaun Nelson 38:182ba91524e4 1022 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1023 PingSlotCtx.PingNb = 128 / ( 1 << periodicity );
Shaun Nelson 38:182ba91524e4 1024 PingSlotCtx.PingPeriod = BeaconCtx.Cfg.WindowSlots / PingSlotCtx.PingNb;
Shaun Nelson 38:182ba91524e4 1025 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1026 }
Shaun Nelson 38:182ba91524e4 1027
Shaun Nelson 38:182ba91524e4 1028 void LoRaMacClassBHaltBeaconing( void )
Shaun Nelson 38:182ba91524e4 1029 {
Shaun Nelson 38:182ba91524e4 1030 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1031 if( ( BeaconState == BEACON_STATE_TIMEOUT ) ||
Shaun Nelson 38:182ba91524e4 1032 ( BeaconState == BEACON_STATE_SWITCH_CLASS ) )
Shaun Nelson 38:182ba91524e4 1033 {
Shaun Nelson 38:182ba91524e4 1034 // Update the state machine before halt
Shaun Nelson 38:182ba91524e4 1035 LoRaMacClassBBeaconTimerEvent( );
Shaun Nelson 38:182ba91524e4 1036 }
Shaun Nelson 38:182ba91524e4 1037
Shaun Nelson 38:182ba91524e4 1038 // Halt beacon state machine
Shaun Nelson 38:182ba91524e4 1039 BeaconState = BEACON_STATE_HALT;
Shaun Nelson 38:182ba91524e4 1040
Shaun Nelson 38:182ba91524e4 1041 // Halt ping slot state machine
Shaun Nelson 38:182ba91524e4 1042 TimerStop( &BeaconTimer );
Shaun Nelson 40:f7ce84dc9363 1043 BeaconEventTime = 0;
Shaun Nelson 38:182ba91524e4 1044
Shaun Nelson 38:182ba91524e4 1045 // Halt ping slot state machine
Shaun Nelson 38:182ba91524e4 1046 TimerStop( &PingSlotTimer );
Shaun Nelson 38:182ba91524e4 1047
Shaun Nelson 38:182ba91524e4 1048 // Halt multicast ping slot state machine
Shaun Nelson 38:182ba91524e4 1049 TimerStop( &MulticastSlotTimer );
Shaun Nelson 38:182ba91524e4 1050 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1051 }
Shaun Nelson 38:182ba91524e4 1052
Shaun Nelson 38:182ba91524e4 1053 void LoRaMacClassBResumeBeaconing( void )
Shaun Nelson 38:182ba91524e4 1054 {
Shaun Nelson 38:182ba91524e4 1055 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1056 if( BeaconState == BEACON_STATE_HALT )
Shaun Nelson 38:182ba91524e4 1057 {
Shaun Nelson 38:182ba91524e4 1058 BeaconCtx.Ctrl.ResumeBeaconing = 1;
Shaun Nelson 38:182ba91524e4 1059
Shaun Nelson 38:182ba91524e4 1060 // Set default state
Shaun Nelson 38:182ba91524e4 1061 BeaconState = BEACON_STATE_LOCKED;
Shaun Nelson 38:182ba91524e4 1062
Shaun Nelson 38:182ba91524e4 1063 if( BeaconCtx.Ctrl.BeaconAcquired == 0 )
Shaun Nelson 38:182ba91524e4 1064 {
Shaun Nelson 38:182ba91524e4 1065 // Set the default state for beacon less operation
Shaun Nelson 38:182ba91524e4 1066 BeaconState = BEACON_STATE_REACQUISITION;
Shaun Nelson 38:182ba91524e4 1067 }
Shaun Nelson 38:182ba91524e4 1068 TimerSetValue( &BeaconTimer, 1 );
Shaun Nelson 38:182ba91524e4 1069 TimerStart( &BeaconTimer );
Shaun Nelson 40:f7ce84dc9363 1070 BeaconEventTime = 1;
Shaun Nelson 38:182ba91524e4 1071 }
Shaun Nelson 38:182ba91524e4 1072 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1073 }
Shaun Nelson 38:182ba91524e4 1074
Shaun Nelson 38:182ba91524e4 1075 LoRaMacStatus_t LoRaMacClassBSwitchClass( DeviceClass_t nextClass )
Shaun Nelson 38:182ba91524e4 1076 {
Shaun Nelson 38:182ba91524e4 1077 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1078 if( nextClass == CLASS_B )
Shaun Nelson 38:182ba91524e4 1079 {// Switch to from class a to class b
Shaun Nelson 38:182ba91524e4 1080 if( ( BeaconCtx.Ctrl.BeaconMode == 1 ) && ( PingSlotCtx.Ctrl.Assigned == 1 ) )
Shaun Nelson 38:182ba91524e4 1081 {
Shaun Nelson 38:182ba91524e4 1082 return LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1083 }
Shaun Nelson 38:182ba91524e4 1084 }
Shaun Nelson 38:182ba91524e4 1085 if( nextClass == CLASS_A )
Shaun Nelson 38:182ba91524e4 1086 {// Switch from class b to class a
Shaun Nelson 38:182ba91524e4 1087 BeaconState = BEACON_STATE_ACQUISITION;
Shaun Nelson 38:182ba91524e4 1088 return LORAMAC_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1089 }
Shaun Nelson 38:182ba91524e4 1090 return LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 1091 #else
Shaun Nelson 38:182ba91524e4 1092 return LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 1093 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1094 }
Shaun Nelson 38:182ba91524e4 1095
Shaun Nelson 38:182ba91524e4 1096 LoRaMacStatus_t LoRaMacClassBMibGetRequestConfirm( MibRequestConfirm_t *mibGet )
Shaun Nelson 38:182ba91524e4 1097 {
Shaun Nelson 38:182ba91524e4 1098 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1099 LoRaMacStatus_t status;
Shaun Nelson 38:182ba91524e4 1100
Shaun Nelson 38:182ba91524e4 1101 switch( mibGet->Type )
Shaun Nelson 38:182ba91524e4 1102 {
Shaun Nelson 38:182ba91524e4 1103 case MIB_BEACON_INTERVAL:
Shaun Nelson 38:182ba91524e4 1104 {
Shaun Nelson 38:182ba91524e4 1105 mibGet->Param.BeaconInterval = BeaconCtx.Cfg.Interval;
Shaun Nelson 38:182ba91524e4 1106 break;
Shaun Nelson 38:182ba91524e4 1107 }
Shaun Nelson 38:182ba91524e4 1108 case MIB_BEACON_RESERVED:
Shaun Nelson 38:182ba91524e4 1109 {
Shaun Nelson 38:182ba91524e4 1110 mibGet->Param.BeaconReserved = BeaconCtx.Cfg.Reserved;
Shaun Nelson 38:182ba91524e4 1111 break;
Shaun Nelson 38:182ba91524e4 1112 }
Shaun Nelson 38:182ba91524e4 1113 case MIB_BEACON_GUARD:
Shaun Nelson 38:182ba91524e4 1114 {
Shaun Nelson 38:182ba91524e4 1115 mibGet->Param.BeaconGuard = BeaconCtx.Cfg.Guard;
Shaun Nelson 38:182ba91524e4 1116 break;
Shaun Nelson 38:182ba91524e4 1117 }
Shaun Nelson 38:182ba91524e4 1118 case MIB_BEACON_WINDOW:
Shaun Nelson 38:182ba91524e4 1119 {
Shaun Nelson 38:182ba91524e4 1120 mibGet->Param.BeaconWindow = BeaconCtx.Cfg.Window;
Shaun Nelson 38:182ba91524e4 1121 break;
Shaun Nelson 38:182ba91524e4 1122 }
Shaun Nelson 38:182ba91524e4 1123 case MIB_BEACON_WINDOW_SLOTS:
Shaun Nelson 38:182ba91524e4 1124 {
Shaun Nelson 38:182ba91524e4 1125 mibGet->Param.BeaconWindowSlots = BeaconCtx.Cfg.WindowSlots;
Shaun Nelson 38:182ba91524e4 1126 break;
Shaun Nelson 38:182ba91524e4 1127 }
Shaun Nelson 38:182ba91524e4 1128 case MIB_PING_SLOT_WINDOW:
Shaun Nelson 38:182ba91524e4 1129 {
Shaun Nelson 38:182ba91524e4 1130 mibGet->Param.PingSlotWindow = PingSlotCtx.Cfg.PingSlotWindow;
Shaun Nelson 38:182ba91524e4 1131 break;
Shaun Nelson 38:182ba91524e4 1132 }
Shaun Nelson 38:182ba91524e4 1133 case MIB_BEACON_SYMBOL_TO_DEFAULT:
Shaun Nelson 38:182ba91524e4 1134 {
Shaun Nelson 38:182ba91524e4 1135 mibGet->Param.BeaconSymbolToDefault = BeaconCtx.Cfg.SymbolToDefault;
Shaun Nelson 38:182ba91524e4 1136 break;
Shaun Nelson 38:182ba91524e4 1137 }
Shaun Nelson 38:182ba91524e4 1138 case MIB_BEACON_SYMBOL_TO_EXPANSION_MAX:
Shaun Nelson 38:182ba91524e4 1139 {
Shaun Nelson 38:182ba91524e4 1140 mibGet->Param.BeaconSymbolToExpansionMax = BeaconCtx.Cfg.SymbolToExpansionMax;
Shaun Nelson 38:182ba91524e4 1141 break;
Shaun Nelson 38:182ba91524e4 1142 }
Shaun Nelson 38:182ba91524e4 1143 case MIB_PING_SLOT_SYMBOL_TO_EXPANSION_MAX:
Shaun Nelson 38:182ba91524e4 1144 {
Shaun Nelson 38:182ba91524e4 1145 mibGet->Param.PingSlotSymbolToExpansionMax = PingSlotCtx.Cfg.SymbolToExpansionMax;
Shaun Nelson 38:182ba91524e4 1146 break;
Shaun Nelson 38:182ba91524e4 1147 }
Shaun Nelson 38:182ba91524e4 1148 case MIB_BEACON_SYMBOL_TO_EXPANSION_FACTOR:
Shaun Nelson 38:182ba91524e4 1149 {
Shaun Nelson 38:182ba91524e4 1150 mibGet->Param.BeaconSymbolToExpansionFactor = BeaconCtx.Cfg.SymbolToExpansionFactor;
Shaun Nelson 38:182ba91524e4 1151 break;
Shaun Nelson 38:182ba91524e4 1152 }
Shaun Nelson 38:182ba91524e4 1153 case MIB_PING_SLOT_SYMBOL_TO_EXPANSION_FACTOR:
Shaun Nelson 38:182ba91524e4 1154 {
Shaun Nelson 38:182ba91524e4 1155 mibGet->Param.PingSlotSymbolToExpansionFactor = PingSlotCtx.Cfg.SymbolToExpansionFactor;
Shaun Nelson 38:182ba91524e4 1156 break;
Shaun Nelson 38:182ba91524e4 1157 }
Shaun Nelson 38:182ba91524e4 1158 case MIB_MAX_BEACON_LESS_PERIOD:
Shaun Nelson 38:182ba91524e4 1159 {
Shaun Nelson 38:182ba91524e4 1160 mibGet->Param.MaxBeaconLessPeriod = BeaconCtx.Cfg.MaxBeaconLessPeriod;
Shaun Nelson 38:182ba91524e4 1161 break;
Shaun Nelson 38:182ba91524e4 1162 }
Shaun Nelson 38:182ba91524e4 1163 default:
Shaun Nelson 38:182ba91524e4 1164 {
Shaun Nelson 38:182ba91524e4 1165 status = LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 1166 break;
Shaun Nelson 38:182ba91524e4 1167 }
Shaun Nelson 38:182ba91524e4 1168 }
Shaun Nelson 38:182ba91524e4 1169 return status;
Shaun Nelson 38:182ba91524e4 1170 #else
Shaun Nelson 38:182ba91524e4 1171 return LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 1172 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1173 }
Shaun Nelson 38:182ba91524e4 1174
Shaun Nelson 38:182ba91524e4 1175 LoRaMacStatus_t LoRaMacMibClassBSetRequestConfirm( MibRequestConfirm_t *mibSet )
Shaun Nelson 38:182ba91524e4 1176 {
Shaun Nelson 38:182ba91524e4 1177 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1178 LoRaMacStatus_t status;
Shaun Nelson 38:182ba91524e4 1179
Shaun Nelson 38:182ba91524e4 1180 switch( mibSet->Type )
Shaun Nelson 38:182ba91524e4 1181 {
Shaun Nelson 38:182ba91524e4 1182 case MIB_BEACON_INTERVAL:
Shaun Nelson 38:182ba91524e4 1183 {
Shaun Nelson 38:182ba91524e4 1184 BeaconCtx.Cfg.Interval = mibSet->Param.BeaconInterval;
Shaun Nelson 38:182ba91524e4 1185 break;
Shaun Nelson 38:182ba91524e4 1186 }
Shaun Nelson 38:182ba91524e4 1187 case MIB_BEACON_RESERVED:
Shaun Nelson 38:182ba91524e4 1188 {
Shaun Nelson 38:182ba91524e4 1189 BeaconCtx.Cfg.Reserved = mibSet->Param.BeaconReserved;
Shaun Nelson 38:182ba91524e4 1190 break;
Shaun Nelson 38:182ba91524e4 1191 }
Shaun Nelson 38:182ba91524e4 1192 case MIB_BEACON_GUARD:
Shaun Nelson 38:182ba91524e4 1193 {
Shaun Nelson 38:182ba91524e4 1194 BeaconCtx.Cfg.Guard = mibSet->Param.BeaconGuard;
Shaun Nelson 38:182ba91524e4 1195 break;
Shaun Nelson 38:182ba91524e4 1196 }
Shaun Nelson 38:182ba91524e4 1197 case MIB_BEACON_WINDOW:
Shaun Nelson 38:182ba91524e4 1198 {
Shaun Nelson 38:182ba91524e4 1199 BeaconCtx.Cfg.Window = mibSet->Param.BeaconWindow;
Shaun Nelson 38:182ba91524e4 1200 break;
Shaun Nelson 38:182ba91524e4 1201 }
Shaun Nelson 38:182ba91524e4 1202 case MIB_BEACON_WINDOW_SLOTS:
Shaun Nelson 38:182ba91524e4 1203 {
Shaun Nelson 38:182ba91524e4 1204 BeaconCtx.Cfg.WindowSlots = mibSet->Param.BeaconWindowSlots;
Shaun Nelson 38:182ba91524e4 1205 break;
Shaun Nelson 38:182ba91524e4 1206 }
Shaun Nelson 38:182ba91524e4 1207 case MIB_PING_SLOT_WINDOW:
Shaun Nelson 38:182ba91524e4 1208 {
Shaun Nelson 38:182ba91524e4 1209 PingSlotCtx.Cfg.PingSlotWindow = mibSet->Param.PingSlotWindow;
Shaun Nelson 38:182ba91524e4 1210 break;
Shaun Nelson 38:182ba91524e4 1211 }
Shaun Nelson 38:182ba91524e4 1212 case MIB_BEACON_SYMBOL_TO_DEFAULT:
Shaun Nelson 38:182ba91524e4 1213 {
Shaun Nelson 38:182ba91524e4 1214 BeaconCtx.Cfg.SymbolToDefault = mibSet->Param.BeaconSymbolToDefault;
Shaun Nelson 38:182ba91524e4 1215 break;
Shaun Nelson 38:182ba91524e4 1216 }
Shaun Nelson 38:182ba91524e4 1217 case MIB_BEACON_SYMBOL_TO_EXPANSION_MAX:
Shaun Nelson 38:182ba91524e4 1218 {
Shaun Nelson 38:182ba91524e4 1219 BeaconCtx.Cfg.SymbolToExpansionMax = mibSet->Param.BeaconSymbolToExpansionMax;
Shaun Nelson 38:182ba91524e4 1220 break;
Shaun Nelson 38:182ba91524e4 1221 }
Shaun Nelson 38:182ba91524e4 1222 case MIB_PING_SLOT_SYMBOL_TO_EXPANSION_MAX:
Shaun Nelson 38:182ba91524e4 1223 {
Shaun Nelson 38:182ba91524e4 1224 PingSlotCtx.Cfg.SymbolToExpansionMax = mibSet->Param.PingSlotSymbolToExpansionMax;
Shaun Nelson 38:182ba91524e4 1225 break;
Shaun Nelson 38:182ba91524e4 1226 }
Shaun Nelson 38:182ba91524e4 1227 case MIB_BEACON_SYMBOL_TO_EXPANSION_FACTOR:
Shaun Nelson 38:182ba91524e4 1228 {
Shaun Nelson 38:182ba91524e4 1229 BeaconCtx.Cfg.SymbolToExpansionFactor = mibSet->Param.BeaconSymbolToExpansionFactor;
Shaun Nelson 38:182ba91524e4 1230 break;
Shaun Nelson 38:182ba91524e4 1231 }
Shaun Nelson 38:182ba91524e4 1232 case MIB_PING_SLOT_SYMBOL_TO_EXPANSION_FACTOR:
Shaun Nelson 38:182ba91524e4 1233 {
Shaun Nelson 38:182ba91524e4 1234 PingSlotCtx.Cfg.SymbolToExpansionFactor = mibSet->Param.PingSlotSymbolToExpansionFactor;
Shaun Nelson 38:182ba91524e4 1235 break;
Shaun Nelson 38:182ba91524e4 1236 }
Shaun Nelson 38:182ba91524e4 1237 case MIB_MAX_BEACON_LESS_PERIOD:
Shaun Nelson 38:182ba91524e4 1238 {
Shaun Nelson 38:182ba91524e4 1239 BeaconCtx.Cfg.MaxBeaconLessPeriod = mibSet->Param.MaxBeaconLessPeriod;
Shaun Nelson 38:182ba91524e4 1240 break;
Shaun Nelson 38:182ba91524e4 1241 }
Shaun Nelson 38:182ba91524e4 1242 default:
Shaun Nelson 38:182ba91524e4 1243 {
Shaun Nelson 38:182ba91524e4 1244 status = LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 1245 break;
Shaun Nelson 38:182ba91524e4 1246 }
Shaun Nelson 38:182ba91524e4 1247 }
Shaun Nelson 38:182ba91524e4 1248 return status;
Shaun Nelson 38:182ba91524e4 1249 #else
Shaun Nelson 38:182ba91524e4 1250 return LORAMAC_STATUS_SERVICE_UNKNOWN;
Shaun Nelson 38:182ba91524e4 1251 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1252 }
Shaun Nelson 38:182ba91524e4 1253
Shaun Nelson 38:182ba91524e4 1254 void LoRaMacClassBPingSlotInfoAns( void )
Shaun Nelson 38:182ba91524e4 1255 {
Shaun Nelson 38:182ba91524e4 1256 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1257 uint8_t index = LORA_MAC_MLME_CONFIRM_QUEUE_LEN;
Shaun Nelson 38:182ba91524e4 1258
Shaun Nelson 38:182ba91524e4 1259 index = LoRaMacClassBCallbacks.GetMlmeConfrimIndex( LoRaMacClassBParams.MlmeConfirmQueue, MLME_PING_SLOT_INFO );
Shaun Nelson 38:182ba91524e4 1260 if( index < LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
Shaun Nelson 38:182ba91524e4 1261 {
Shaun Nelson 38:182ba91524e4 1262 LoRaMacClassBParams.MlmeConfirmQueue[index].Status = LORAMAC_EVENT_INFO_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1263 PingSlotCtx.Ctrl.Assigned = 1;
Shaun Nelson 38:182ba91524e4 1264 }
Shaun Nelson 38:182ba91524e4 1265 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1266 }
Shaun Nelson 38:182ba91524e4 1267
Shaun Nelson 38:182ba91524e4 1268 uint8_t LoRaMacClassBPingSlotChannelReq( uint8_t datarate, uint32_t frequency )
Shaun Nelson 38:182ba91524e4 1269 {
Shaun Nelson 38:182ba91524e4 1270 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1271 uint8_t status = 0x03;
Shaun Nelson 38:182ba91524e4 1272 VerifyParams_t verify;
Shaun Nelson 38:182ba91524e4 1273 GetPhyParams_t getPhy;
Shaun Nelson 38:182ba91524e4 1274 PhyParam_t phyParam;
Shaun Nelson 38:182ba91524e4 1275
Shaun Nelson 38:182ba91524e4 1276 if( frequency != 0 )
Shaun Nelson 38:182ba91524e4 1277 {
Shaun Nelson 38:182ba91524e4 1278 if( Radio.CheckRfFrequency( frequency ) == false )
Shaun Nelson 38:182ba91524e4 1279 {
Shaun Nelson 38:182ba91524e4 1280 status &= 0xFE; // Channel frequency KO
Shaun Nelson 38:182ba91524e4 1281 }
Shaun Nelson 38:182ba91524e4 1282
Shaun Nelson 38:182ba91524e4 1283 verify.DatarateParams.Datarate = datarate;
Shaun Nelson 38:182ba91524e4 1284 verify.DatarateParams.DownlinkDwellTime = LoRaMacClassBParams.LoRaMacParams->DownlinkDwellTime;
Shaun Nelson 38:182ba91524e4 1285
Shaun Nelson 38:182ba91524e4 1286 if( RegionVerify( *LoRaMacClassBParams.LoRaMacRegion, &verify, PHY_RX_DR ) == false )
Shaun Nelson 38:182ba91524e4 1287 {
Shaun Nelson 38:182ba91524e4 1288 status &= 0xFD; // Datarate range KO
Shaun Nelson 38:182ba91524e4 1289 }
Shaun Nelson 38:182ba91524e4 1290
Shaun Nelson 38:182ba91524e4 1291 if( status == 0x03 )
Shaun Nelson 38:182ba91524e4 1292 {
Shaun Nelson 38:182ba91524e4 1293 PingSlotCtx.Ctrl.CustomFreq = 1;
Shaun Nelson 38:182ba91524e4 1294 PingSlotCtx.Frequency = frequency;
Shaun Nelson 38:182ba91524e4 1295 PingSlotCtx.Datarate = datarate;
Shaun Nelson 38:182ba91524e4 1296 }
Shaun Nelson 38:182ba91524e4 1297 }
Shaun Nelson 38:182ba91524e4 1298 else
Shaun Nelson 38:182ba91524e4 1299 {
Shaun Nelson 38:182ba91524e4 1300 getPhy.Attribute = PHY_BEACON_CHANNEL_DR;
Shaun Nelson 38:182ba91524e4 1301 phyParam = RegionGetPhyParam( *LoRaMacClassBParams.LoRaMacRegion, &getPhy );
Shaun Nelson 38:182ba91524e4 1302
Shaun Nelson 38:182ba91524e4 1303 PingSlotCtx.Ctrl.CustomFreq = 0;
Shaun Nelson 38:182ba91524e4 1304 PingSlotCtx.Datarate = phyParam.Value;
Shaun Nelson 38:182ba91524e4 1305 }
Shaun Nelson 38:182ba91524e4 1306 return status;
Shaun Nelson 38:182ba91524e4 1307 #else
Shaun Nelson 38:182ba91524e4 1308 return 0;
Shaun Nelson 38:182ba91524e4 1309 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1310 }
Shaun Nelson 38:182ba91524e4 1311
Shaun Nelson 38:182ba91524e4 1312 void LoRaMacClassBBeaconTimingAns( uint16_t beaconTimingDelay, uint8_t beaconTimingChannel )
Shaun Nelson 38:182ba91524e4 1313 {
Shaun Nelson 38:182ba91524e4 1314 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1315 uint8_t index = LORA_MAC_MLME_CONFIRM_QUEUE_LEN;
Shaun Nelson 38:182ba91524e4 1316 TimerTime_t currentTime = TimerGetCurrentTime( );
Shaun Nelson 38:182ba91524e4 1317
Shaun Nelson 38:182ba91524e4 1318 BeaconCtx.BeaconTimingDelay = ( BeaconCtx.Cfg.DelayBeaconTimingAns * beaconTimingDelay );
Shaun Nelson 38:182ba91524e4 1319 BeaconCtx.BeaconTimingChannel = beaconTimingChannel;
Shaun Nelson 38:182ba91524e4 1320
Shaun Nelson 38:182ba91524e4 1321 index = LoRaMacClassBCallbacks.GetMlmeConfrimIndex( LoRaMacClassBParams.MlmeConfirmQueue, MLME_BEACON_TIMING );
Shaun Nelson 38:182ba91524e4 1322 if( index < LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
Shaun Nelson 38:182ba91524e4 1323 {
Shaun Nelson 38:182ba91524e4 1324 if( BeaconCtx.BeaconTimingDelay > BeaconCtx.Cfg.Interval )
Shaun Nelson 38:182ba91524e4 1325 {
Shaun Nelson 38:182ba91524e4 1326 // We missed the beacon already
Shaun Nelson 38:182ba91524e4 1327 BeaconCtx.BeaconTimingDelay = 0;
Shaun Nelson 38:182ba91524e4 1328 BeaconCtx.BeaconTimingChannel = 0;
Shaun Nelson 48:81c0f4c4dd2c 1329 BeaconCtx.BeaconTimingAnsTime = 0;
Shaun Nelson 38:182ba91524e4 1330 LoRaMacClassBParams.MlmeConfirmQueue[index].Status = LORAMAC_EVENT_INFO_STATUS_BEACON_NOT_FOUND;
Shaun Nelson 38:182ba91524e4 1331 }
Shaun Nelson 38:182ba91524e4 1332 else
Shaun Nelson 38:182ba91524e4 1333 {
Shaun Nelson 38:182ba91524e4 1334 BeaconCtx.Ctrl.BeaconDelaySet = 1;
Shaun Nelson 38:182ba91524e4 1335 BeaconCtx.Ctrl.BeaconChannelSet = 1;
Shaun Nelson 48:81c0f4c4dd2c 1336 BeaconCtx.BeaconTimingAnsTime = currentTime;
Shaun Nelson 38:182ba91524e4 1337 BeaconCtx.NextBeaconRx = currentTime + BeaconCtx.BeaconTimingDelay;
Shaun Nelson 38:182ba91524e4 1338 LoRaMacClassBParams.MlmeConfirmQueue[index].Status = LORAMAC_EVENT_INFO_STATUS_OK;
Shaun Nelson 38:182ba91524e4 1339 }
Shaun Nelson 38:182ba91524e4 1340
Shaun Nelson 38:182ba91524e4 1341 LoRaMacClassBParams.MlmeConfirm->BeaconTimingDelay = BeaconCtx.BeaconTimingDelay;
Shaun Nelson 38:182ba91524e4 1342 LoRaMacClassBParams.MlmeConfirm->BeaconTimingChannel = BeaconCtx.BeaconTimingChannel;
Shaun Nelson 38:182ba91524e4 1343 }
Shaun Nelson 38:182ba91524e4 1344 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1345 }
Shaun Nelson 38:182ba91524e4 1346
Shaun Nelson 38:182ba91524e4 1347 bool LoRaMacClassBBeaconFreqReq( uint32_t frequency )
Shaun Nelson 38:182ba91524e4 1348 {
Shaun Nelson 38:182ba91524e4 1349 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1350 if( frequency != 0 )
Shaun Nelson 38:182ba91524e4 1351 {
Shaun Nelson 38:182ba91524e4 1352 if( Radio.CheckRfFrequency( frequency ) == true )
Shaun Nelson 38:182ba91524e4 1353 {
Shaun Nelson 38:182ba91524e4 1354 BeaconCtx.Ctrl.CustomFreq = 1;
Shaun Nelson 38:182ba91524e4 1355 BeaconCtx.Frequency = frequency;
Shaun Nelson 38:182ba91524e4 1356 return true;
Shaun Nelson 38:182ba91524e4 1357 }
Shaun Nelson 38:182ba91524e4 1358 }
Shaun Nelson 38:182ba91524e4 1359 else
Shaun Nelson 38:182ba91524e4 1360 {
Shaun Nelson 38:182ba91524e4 1361 BeaconCtx.Ctrl.CustomFreq = 0;
Shaun Nelson 38:182ba91524e4 1362 return true;
Shaun Nelson 38:182ba91524e4 1363 }
Shaun Nelson 38:182ba91524e4 1364 return false;
Shaun Nelson 38:182ba91524e4 1365 #else
Shaun Nelson 38:182ba91524e4 1366 return false;
Shaun Nelson 38:182ba91524e4 1367 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1368 }
Shaun Nelson 38:182ba91524e4 1369
Shaun Nelson 38:182ba91524e4 1370 TimerTime_t LoRaMacClassBGetBeaconReservedTime( void )
Shaun Nelson 38:182ba91524e4 1371 {
Shaun Nelson 38:182ba91524e4 1372 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1373 return BeaconCtx.Cfg.Reserved;
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 }
Shaun Nelson 38:182ba91524e4 1378
Shaun Nelson 38:182ba91524e4 1379 TimerTime_t LoRaMacClassBGetPingSlotWinTime( void )
Shaun Nelson 38:182ba91524e4 1380 {
Shaun Nelson 38:182ba91524e4 1381 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1382 return PingSlotCtx.Cfg.PingSlotWindow;
Shaun Nelson 38:182ba91524e4 1383 #else
Shaun Nelson 38:182ba91524e4 1384 return 0;
Shaun Nelson 38:182ba91524e4 1385 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1386 }
Shaun Nelson 38:182ba91524e4 1387
Shaun Nelson 38:182ba91524e4 1388 TimerTime_t LoRaMacClassBIsUplinkCollision( TimerTime_t txTimeOnAir )
Shaun Nelson 38:182ba91524e4 1389 {
Shaun Nelson 38:182ba91524e4 1390 #ifdef LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1391 TimerTime_t currentTime = TimerGetCurrentTime( );
Shaun Nelson 38:182ba91524e4 1392 TimerTime_t beaconReserved = 0;
Shaun Nelson 38:182ba91524e4 1393
Shaun Nelson 38:182ba91524e4 1394 beaconReserved = BeaconCtx.NextBeaconRx -
Shaun Nelson 38:182ba91524e4 1395 BeaconCtx.Cfg.Guard -
Shaun Nelson 38:182ba91524e4 1396 LoRaMacClassBParams.LoRaMacParams->ReceiveDelay1 -
Shaun Nelson 38:182ba91524e4 1397 LoRaMacClassBParams.LoRaMacParams->ReceiveDelay2 -
Shaun Nelson 38:182ba91524e4 1398 txTimeOnAir;
Shaun Nelson 38:182ba91524e4 1399
Shaun Nelson 38:182ba91524e4 1400 // Check if the next beacon will be received during the next uplink.
Shaun Nelson 38:182ba91524e4 1401 if( ( currentTime >= beaconReserved ) && ( currentTime < ( BeaconCtx.NextBeaconRx + BeaconCtx.Cfg.Reserved ) ) )
Shaun Nelson 38:182ba91524e4 1402 {// Next beacon will be sent during the next uplink.
Shaun Nelson 38:182ba91524e4 1403 return BeaconCtx.Cfg.Reserved;
Shaun Nelson 38:182ba91524e4 1404 }
Shaun Nelson 38:182ba91524e4 1405 return 0;
Shaun Nelson 38:182ba91524e4 1406 #else
Shaun Nelson 38:182ba91524e4 1407 return 0;
Shaun Nelson 38:182ba91524e4 1408 #endif // LORAMAC_CLASSB_ENABLED
Shaun Nelson 38:182ba91524e4 1409 }