Senet / LoRaWAN-lib

Fork of LoRaWAN-lib by canuck lehead

Committer:
Shaun Nelson
Date:
Wed Aug 09 16:20:21 2017 -0400
Branch:
class_b
Revision:
38:182ba91524e4
Child:
40:f7ce84dc9363
Synchronized with  https://github.com/Senetco/LoRaMac-node/commit/6cb21de99eaa65caad9d911318df8875867a6e60

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