@@ -99,7 +99,7 @@ Arduino_LoRaWAN::BuildSessionState(
99
99
// handle EU like regions
100
100
#if CFG_LMIC_EU_like
101
101
State.V1 .Channels .Header .Tag = State.V1 .Channels .Header .kEUlike ;
102
- State.V1 .Channels .Header .Tag = sizeof (State.V1 .Channels .EUlike );
102
+ State.V1 .Channels .Header .Size = sizeof (State.V1 .Channels .EUlike );
103
103
State.V1 .Channels .EUlike .clearAll ();
104
104
constexpr unsigned maxCh = MAX_CHANNELS < State.V1 .Channels .EUlike .nCh ? MAX_CHANNELS : State.V1 .Channels .EUlike .nCh ;
105
105
State.V1 .Channels .EUlike .ChannelMap = LMIC.channelMap ;
@@ -135,8 +135,8 @@ Arduino_LoRaWAN::BuildSessionState(
135
135
}
136
136
137
137
#elif CFG_LMIC_US_like
138
- State.V1 .Channels .Header .Tag = State.V1 .Channels .Header .kEUlike ;
139
- State.V1 .Channels .Header .Tag = sizeof (State.V1 .Channels .USlike );
138
+ State.V1 .Channels .Header .Tag = State.V1 .Channels .Header .kUSlike ;
139
+ State.V1 .Channels .Header .Size = sizeof (State.V1 .Channels .USlike );
140
140
141
141
#if ARDUINO_LMIC_VERSION_COMPARE_GE(ARDUINO_LMIC_VERSION, ARDUINO_LMIC_VERSION_CALC(3,99,0,1))
142
142
static_assert (
@@ -257,6 +257,43 @@ Name: Arduino_LoRaWAN::ApplySessionState()
257
257
258
258
*/
259
259
260
+ bool Arduino_LoRaWAN::IsValidState (const Arduino_LoRaWAN::SessionState &state) const
261
+ {
262
+ // do not apply the session state unless it roughly matches our configuration.
263
+ if (! state.isValid ())
264
+ return false ;
265
+
266
+ // make sure region and country match. TODO: make sure network matches.
267
+ if (! (Arduino_LoRaWAN::Region (state.V1 .Region ) == this ->GetRegion () &&
268
+ state.V1 .Country == uint16_t (this ->GetCountryCode ())))
269
+ return false ;
270
+
271
+ // it matches!
272
+ return true ;
273
+ }
274
+
275
+ bool Arduino_LoRaWAN::SessionState::isValid () const
276
+ {
277
+ if (! (this ->Header .Tag == kSessionStateTag_V1 &&
278
+ this ->Header .Size == sizeof (*this )))
279
+ return false ;
280
+
281
+ switch (this ->V1 .Channels .Header .Tag )
282
+ {
283
+ case Arduino_LoRaWAN::SessionChannelMask_Header::eMaskKind::kEUlike :
284
+ return this ->V1 .Channels .Header .Size == sizeof (this ->V1 .Channels .EUlike );
285
+
286
+ case Arduino_LoRaWAN::SessionChannelMask_Header::eMaskKind::kUSlike :
287
+ return this ->V1 .Channels .Header .Size == sizeof (this ->V1 .Channels .USlike );
288
+
289
+ case Arduino_LoRaWAN::SessionChannelMask_Header::eMaskKind::kCNlike :
290
+ return this ->V1 .Channels .Header .Size == sizeof (this ->V1 .Channels .CNlike );
291
+
292
+ default :
293
+ return false ;
294
+ }
295
+ }
296
+
260
297
#define FUNCTION " Arduino_LoRaWAN::ApplySessionState"
261
298
262
299
bool
@@ -265,124 +302,115 @@ Arduino_LoRaWAN::ApplySessionState(
265
302
)
266
303
{
267
304
// do not apply the session state unless it roughly matches our configuration.
268
- if (State.Header .Tag == kSessionStateTag_V1 &&
269
- Arduino_LoRaWAN::Region (State.V1 .Region ) == this ->GetRegion () &&
270
- State.V1 .Country == uint16_t (this ->GetCountryCode ())
271
- )
272
- {
273
- auto const tNow = os_getTime ();
305
+ if (! this ->IsValidState (State))
306
+ return false ;
274
307
275
- // record that we've done it.
276
- this ->m_savedSessionState = State;
308
+ auto const tNow = os_getTime ();
309
+
310
+ // record that we've done it.
311
+ this ->m_savedSessionState = State;
277
312
278
- // set FcntUp, FcntDown, and session state
279
- LMIC.datarate = State.V1 .LinkDR ;
313
+ // set FcntUp, FcntDown, and session state
314
+ LMIC.datarate = State.V1 .LinkDR ;
280
315
281
- // set the uplink and downlink count
282
- LMIC.seqnoDn = State.V1 .FCntDown ;
283
- LMIC.seqnoUp = State.V1 .FCntUp ;
316
+ // set the uplink and downlink count
317
+ LMIC.seqnoDn = State.V1 .FCntDown ;
318
+ LMIC.seqnoUp = State.V1 .FCntUp ;
284
319
285
- //
286
- // TODO([email protected] ): State.V1.gpsTime can be used to tweak the saved cycle
287
- // time and also as a fallback if the system clock is not robust. but right
288
- // now we ignore it.
289
- //
320
+ //
321
+ // TODO([email protected] ): State.V1.gpsTime can be used to tweak the saved cycle
322
+ // time and also as a fallback if the system clock is not robust. but right
323
+ // now we ignore it.
324
+ //
290
325
291
- // conservatively set the global avail time.
292
- LMIC.globalDutyAvail = tNow + State.V1 .globalAvail ;
326
+ // conservatively set the global avail time.
327
+ LMIC.globalDutyAvail = tNow + State.V1 .globalAvail ;
293
328
294
- // set the Rx2 frequency
295
- LMIC.dn2Freq = State.V1 .Rx2Frequency ;
329
+ // set the Rx2 frequency
330
+ LMIC.dn2Freq = State.V1 .Rx2Frequency ;
296
331
297
332
#if !defined(DISABLE_PING)
298
- // set the ping frequency
299
- LMIC.ping .freq = State.V1 .PingFrequency ;
333
+ // set the ping frequency
334
+ LMIC.ping .freq = State.V1 .PingFrequency ;
300
335
#endif
301
336
302
- LMIC.adrAckReq = State.V1 .LinkIntegrity ;
303
- LMIC.adrTxPow = State.V1 .TxPower ;
304
- LMIC.upRepeat = State.V1 .Redundancy ;
305
- LMIC.globalDutyRate = State.V1 .DutyCycle ;
306
- LMIC.rx1DrOffset = State.V1 .Rx1DRoffset ;
307
- LMIC.dn2Dr = State.V1 .Rx2DataRate ;
308
- LMIC.rxDelay = State.V1 .RxDelay ;
337
+ LMIC.adrAckReq = State.V1 .LinkIntegrity ;
338
+ LMIC.adrTxPow = State.V1 .TxPower ;
339
+ LMIC.upRepeat = State.V1 .Redundancy ;
340
+ LMIC.globalDutyRate = State.V1 .DutyCycle ;
341
+ LMIC.rx1DrOffset = State.V1 .Rx1DRoffset ;
342
+ LMIC.dn2Dr = State.V1 .Rx2DataRate ;
343
+ LMIC.rxDelay = State.V1 .RxDelay ;
309
344
310
345
#if LMIC_ENABLE_TxParamSetupReq
311
- LMIC.txParam = State.V1 .TxParam ;
346
+ LMIC.txParam = State.V1 .TxParam ;
312
347
#endif
313
348
#if !defined(DISABLE_BEACONS)
314
- LMIC.bcnChnl = State.V1 .BeaconChannel ;
349
+ LMIC.bcnChnl = State.V1 .BeaconChannel ;
315
350
#endif
316
351
#if !defined(DISABLE_PING)
317
- LMIC.ping .dr = State.V1 .PingDr ;
352
+ LMIC.ping .dr = State.V1 .PingDr ;
318
353
#endif
319
- LMIC.dn2Ans = State.V1 .MacRxParamAns ;
320
- LMIC.macDlChannelAns = State.V1 .MacDlChannelAns ;
321
- LMIC.macRxTimingSetupAns = State.V1 .MacRxTimingSetupAns ;
354
+ LMIC.dn2Ans = State.V1 .MacRxParamAns ;
355
+ LMIC.macDlChannelAns = State.V1 .MacDlChannelAns ;
356
+ LMIC.macRxTimingSetupAns = State.V1 .MacRxTimingSetupAns ;
322
357
323
358
#if CFG_LMIC_EU_like
324
- // don't turn off bits: user can't fool us here.
325
- // we can get the immutable channels from the
326
- // channelMap value after reset.
327
- auto const resetMap = LMIC.channelMap ;
328
- auto const & euLike = State.V1 .Channels .EUlike ;
329
- LMIC.channelMap |= euLike.ChannelMap ;
359
+ // don't turn off bits: user can't fool us here.
360
+ // we can get the immutable channels from the
361
+ // channelMap value after reset.
362
+ auto const resetMap = LMIC.channelMap ;
363
+ auto const & euLike = State.V1 .Channels .EUlike ;
364
+ LMIC.channelMap |= euLike.ChannelMap ;
330
365
#if ARDUINO_LMIC_VERSION_COMPARE_GE(ARDUINO_LMIC_VERSION, ARDUINO_LMIC_VERSION_CALC(3,99,0,1))
331
- LMIC.channelShuffleMap = euLike.ChannelShuffleMap ;
366
+ LMIC.channelShuffleMap = euLike.ChannelShuffleMap ;
332
367
#endif
333
- for (unsigned ch = 0 ; ch < MAX_CHANNELS; ++ch)
368
+ for (unsigned ch = 0 ; ch < MAX_CHANNELS; ++ch)
369
+ {
370
+ if ((resetMap & (decltype (resetMap)(1 ) << ch)) == 0 )
334
371
{
335
- if ((resetMap & (decltype (resetMap)(1 ) << ch)) == 0 )
336
- {
337
- // copy data -- note that the saved band number is encoded
338
- LMIC_setupChannel (
339
- ch,
340
- euLike.getFrequency (euLike.UplinkFreq , ch),
341
- euLike.ChannelDrMap [ch],
342
- euLike.getBand (ch)
343
- );
372
+ // copy data -- note that the saved band number is encoded
373
+ LMIC_setupChannel (
374
+ ch,
375
+ euLike.getFrequency (euLike.UplinkFreq , ch),
376
+ euLike.ChannelDrMap [ch],
377
+ euLike.getBand (ch)
378
+ );
344
379
#if !defined(DISABLE_MCMD_DlChannelReq)
345
- LMIC.channelDlFreq [ch] = euLike.getFrequency (euLike.DownlinkFreq , ch);
380
+ LMIC.channelDlFreq [ch] = euLike.getFrequency (euLike.DownlinkFreq , ch);
346
381
#endif
347
- }
348
382
}
383
+ }
349
384
350
- for (unsigned band = 0 ; band < MAX_BANDS; ++band)
351
- {
352
- LMIC.bands [band].txcap = euLike.Bands [band].txDutyDenom ;
353
- LMIC.bands [band].txpow = euLike.Bands [band].txPower ;
354
- LMIC.bands [band].lastchnl = euLike.Bands [band].lastChannel ;
355
- // Heuristic; we don't know how long has passed since we saved
356
- // this, because we don't currently have GPS time available.
357
- // Conservatively reserve time from now.
358
- LMIC.bands [band].avail = tNow + euLike.Bands [band].ostimeAvail ;
359
- }
385
+ for (unsigned band = 0 ; band < MAX_BANDS; ++band)
386
+ {
387
+ LMIC.bands [band].txcap = euLike.Bands [band].txDutyDenom ;
388
+ LMIC.bands [band].txpow = euLike.Bands [band].txPower ;
389
+ LMIC.bands [band].lastchnl = euLike.Bands [band].lastChannel ;
390
+ // Heuristic; we don't know how long has passed since we saved
391
+ // this, because we don't currently have GPS time available.
392
+ // Conservatively reserve time from now.
393
+ LMIC.bands [band].avail = tNow + euLike.Bands [band].ostimeAvail ;
394
+ }
360
395
361
396
#elif CFG_LMIC_US_like
362
397
# if ARDUINO_LMIC_VERSION_COMPARE_GE(ARDUINO_LMIC_VERSION, ARDUINO_LMIC_VERSION_CALC(3,99,0,1))
363
- static_assert (sizeof (LMIC.channelShuffleMap ) == sizeof (State.V1 .Channels .USlike .ChannelShuffleMap ),
364
- " shuffle map doesn't match" );
365
- // copy the shuffle map bits
366
- memcpy (LMIC.channelShuffleMap , State.V1 .Channels .USlike .ChannelShuffleMap , sizeof (LMIC.channelShuffleMap ));
398
+ static_assert (sizeof (LMIC.channelShuffleMap ) == sizeof (State.V1 .Channels .USlike .ChannelShuffleMap ),
399
+ " shuffle map doesn't match" );
400
+ // copy the shuffle map bits
401
+ memcpy (LMIC.channelShuffleMap , State.V1 .Channels .USlike .ChannelShuffleMap , sizeof (LMIC.channelShuffleMap ));
367
402
# endif
368
- // copy the enabled states
369
- for (unsigned ch = 0 ; ch < State.V1 .Channels .USlike .nCh ; ++ch)
370
- {
371
- const bool state = State.V1 .Channels .USlike .isEnabled (ch);
372
-
373
- if (state)
374
- LMIC_enableChannel (ch);
375
- else
376
- LMIC_disableChannel (ch);
377
- }
378
- #endif
379
-
380
- return true ;
381
- }
382
- else
403
+ // copy the enabled states
404
+ for (unsigned ch = 0 ; ch < State.V1 .Channels .USlike .nCh ; ++ch)
383
405
{
384
- return false ;
406
+ const bool state = State.V1 .Channels .USlike .isEnabled (ch);
407
+
408
+ if (state)
409
+ LMIC_enableChannel (ch);
410
+ else
411
+ LMIC_disableChannel (ch);
385
412
}
413
+ #endif
386
414
}
387
415
388
416
#undef FUNCTION
0 commit comments