84
84
*/
85
85
#define BACKOFF_DC_24_HOURS 10000
86
86
87
+ /*!
88
+ * Maximum value for the ADR ack counter
89
+ */
90
+ #define ADR_ACK_COUNTER_MAX 0xFFFFFFFF
91
+
87
92
/*!
88
93
* LoRaMac internal states
89
94
*/
@@ -664,6 +669,16 @@ static bool CheckRetransUnconfirmedUplink( void );
664
669
*/
665
670
static bool CheckRetransConfirmedUplink ( void );
666
671
672
+ /*!
673
+ * \brief Increases the ADR ack counter. Takes the maximum
674
+ * value into account.
675
+ *
676
+ * \param [IN] counter Current counter value.
677
+ *
678
+ * \retval Returns the next counter value.
679
+ */
680
+ static uint32_t IncreaseAdrAckCounter ( uint32_t counter );
681
+
667
682
/*!
668
683
* \brief Stops the uplink retransmission
669
684
*
@@ -1971,38 +1986,79 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm
1971
1986
uint8_t linkAdrNbRep = 0 ;
1972
1987
uint8_t linkAdrNbBytesParsed = 0 ;
1973
1988
1989
+ // The end node is allowed to process one block of LinkAdrRequests.
1990
+ // It must ignore subsequent blocks
1974
1991
if ( adrBlockFound == false )
1975
1992
{
1976
1993
adrBlockFound = true;
1977
1994
1978
- // Fill parameter structure
1979
- linkAdrReq .Payload = & payload [macIndex - 1 ];
1980
- linkAdrReq .PayloadSize = commandsSize - ( macIndex - 1 );
1981
- linkAdrReq .AdrEnabled = MacCtx .NvmCtx -> AdrCtrlOn ;
1982
- linkAdrReq .UplinkDwellTime = MacCtx .NvmCtx -> MacParams .UplinkDwellTime ;
1983
- linkAdrReq .CurrentDatarate = MacCtx .NvmCtx -> MacParams .ChannelsDatarate ;
1984
- linkAdrReq .CurrentTxPower = MacCtx .NvmCtx -> MacParams .ChannelsTxPower ;
1985
- linkAdrReq .CurrentNbRep = MacCtx .NvmCtx -> MacParams .ChannelsNbTrans ;
1986
- linkAdrReq .Version = MacCtx .NvmCtx -> Version ;
1987
-
1988
- // Process the ADR requests
1989
- status = RegionLinkAdrReq ( MacCtx .NvmCtx -> Region , & linkAdrReq , & linkAdrDatarate ,
1990
- & linkAdrTxPower , & linkAdrNbRep , & linkAdrNbBytesParsed );
1991
-
1992
- if ( ( status & 0x07 ) == 0x07 )
1995
+ do
1993
1996
{
1994
- MacCtx .NvmCtx -> MacParams .ChannelsDatarate = linkAdrDatarate ;
1995
- MacCtx .NvmCtx -> MacParams .ChannelsTxPower = linkAdrTxPower ;
1996
- MacCtx .NvmCtx -> MacParams .ChannelsNbTrans = linkAdrNbRep ;
1997
- }
1998
-
1999
- // Add the answers to the buffer
2000
- for ( uint8_t i = 0 ; i < ( linkAdrNbBytesParsed / 5 ); i ++ )
1997
+ // Fill parameter structure
1998
+ linkAdrReq .Payload = & payload [macIndex - 1 ];
1999
+ linkAdrReq .AdrEnabled = MacCtx .NvmCtx -> AdrCtrlOn ;
2000
+ linkAdrReq .UplinkDwellTime = MacCtx .NvmCtx -> MacParams .UplinkDwellTime ;
2001
+ linkAdrReq .CurrentDatarate = MacCtx .NvmCtx -> MacParams .ChannelsDatarate ;
2002
+ linkAdrReq .CurrentTxPower = MacCtx .NvmCtx -> MacParams .ChannelsTxPower ;
2003
+ linkAdrReq .CurrentNbRep = MacCtx .NvmCtx -> MacParams .ChannelsNbTrans ;
2004
+ linkAdrReq .Version = MacCtx .NvmCtx -> Version ;
2005
+
2006
+ // There is a fundamental difference in reporting the status
2007
+ // of the LinkAdrRequests when ADR is on or off. When ADR is on, every
2008
+ // LinkAdrAns contains the same value. This does not hold when ADR is off,
2009
+ // where every LinkAdrAns requires an individual status.
2010
+ if ( MacCtx .NvmCtx -> AdrCtrlOn == true )
2011
+ {
2012
+ // When ADR is on, the function RegionLinkAdrReq will take care
2013
+ // about the parsing and interpretation of the LinkAdrRequest block and
2014
+ // it provides one status which shall be applied to every LinkAdrAns
2015
+ linkAdrReq .PayloadSize = commandsSize - ( macIndex - 1 );
2016
+ }
2017
+ else
2018
+ {
2019
+ // When ADR is off, this function will loop over the individual LinkAdrRequests
2020
+ // and will call RegionLinkAdrReq for each individually, as every request
2021
+ // requires an individual answer.
2022
+ // When ADR is off, the function RegionLinkAdrReq ignores the new values for
2023
+ // ChannelsDatarate, ChannelsTxPower and ChannelsNbTrans.
2024
+ linkAdrReq .PayloadSize = 5 ;
2025
+ }
2026
+
2027
+ // Process the ADR requests
2028
+ status = RegionLinkAdrReq ( MacCtx .NvmCtx -> Region , & linkAdrReq , & linkAdrDatarate ,
2029
+ & linkAdrTxPower , & linkAdrNbRep , & linkAdrNbBytesParsed );
2030
+
2031
+ if ( ( status & 0x07 ) == 0x07 )
2032
+ {
2033
+ MacCtx .NvmCtx -> MacParams .ChannelsDatarate = linkAdrDatarate ;
2034
+ MacCtx .NvmCtx -> MacParams .ChannelsTxPower = linkAdrTxPower ;
2035
+ MacCtx .NvmCtx -> MacParams .ChannelsNbTrans = linkAdrNbRep ;
2036
+ }
2037
+
2038
+ // Add the answers to the buffer
2039
+ for ( uint8_t i = 0 ; i < ( linkAdrNbBytesParsed / 5 ); i ++ )
2040
+ {
2041
+ LoRaMacCommandsAddCmd ( MOTE_MAC_LINK_ADR_ANS , & status , 1 );
2042
+ }
2043
+ // Update MAC index
2044
+ macIndex += linkAdrNbBytesParsed - 1 ;
2045
+
2046
+ // Check to prevent invalid access
2047
+ if ( macIndex >= commandsSize )
2048
+ break ;
2049
+
2050
+ } while ( payload [macIndex ++ ] == SRV_MAC_LINK_ADR_REQ );
2051
+
2052
+ if ( macIndex < commandsSize )
2001
2053
{
2002
- LoRaMacCommandsAddCmd ( MOTE_MAC_LINK_ADR_ANS , & status , 1 );
2054
+ // Decrease the index such that it points to the next MAC command
2055
+ macIndex -- ;
2003
2056
}
2004
- // Update MAC index
2005
- macIndex += linkAdrNbBytesParsed - 1 ;
2057
+ }
2058
+ else
2059
+ {
2060
+ // Increase the index by the MAC command size (without command)
2061
+ macIndex += 4 ;
2006
2062
}
2007
2063
break ;
2008
2064
}
@@ -2298,19 +2354,20 @@ LoRaMacStatus_t Send( LoRaMacHeader_t* macHdr, uint8_t fPort, void* fBuffer, uin
2298
2354
}
2299
2355
2300
2356
// ADR next request
2301
- adrNext .Version = MacCtx .NvmCtx -> Version ;
2302
2357
adrNext .UpdateChanMask = true;
2303
2358
adrNext .AdrEnabled = fCtrl .Bits .Adr ;
2304
2359
adrNext .AdrAckCounter = MacCtx .NvmCtx -> AdrAckCounter ;
2305
2360
adrNext .AdrAckLimit = MacCtx .AdrAckLimit ;
2306
2361
adrNext .AdrAckDelay = MacCtx .AdrAckDelay ;
2307
2362
adrNext .Datarate = MacCtx .NvmCtx -> MacParams .ChannelsDatarate ;
2308
2363
adrNext .TxPower = MacCtx .NvmCtx -> MacParams .ChannelsTxPower ;
2364
+ adrNext .NbTrans = MacCtx .ChannelsNbTransCounter ;
2309
2365
adrNext .UplinkDwellTime = MacCtx .NvmCtx -> MacParams .UplinkDwellTime ;
2310
2366
adrNext .Region = MacCtx .NvmCtx -> Region ;
2311
2367
2312
2368
fCtrl .Bits .AdrAckReq = LoRaMacAdrCalcNext ( & adrNext , & MacCtx .NvmCtx -> MacParams .ChannelsDatarate ,
2313
- & MacCtx .NvmCtx -> MacParams .ChannelsTxPower , & adrAckCounter );
2369
+ & MacCtx .NvmCtx -> MacParams .ChannelsTxPower ,
2370
+ & MacCtx .ChannelsNbTransCounter , & adrAckCounter );
2314
2371
2315
2372
// Prepare the frame
2316
2373
status = PrepareFrame ( macHdr , & fCtrl , fPort , fBuffer , fBufferSize );
@@ -3087,6 +3144,15 @@ static bool CheckRetransConfirmedUplink( void )
3087
3144
return false;
3088
3145
}
3089
3146
3147
+ static uint32_t IncreaseAdrAckCounter ( uint32_t counter )
3148
+ {
3149
+ if ( counter < ADR_ACK_COUNTER_MAX )
3150
+ {
3151
+ counter ++ ;
3152
+ }
3153
+ return counter ;
3154
+ }
3155
+
3090
3156
static bool StopRetransmission ( void )
3091
3157
{
3092
3158
if ( ( MacCtx .MacFlags .Bits .McpsInd == 0 ) ||
@@ -3442,6 +3508,7 @@ LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo )
3442
3508
uint32_t adrAckCounter = MacCtx .NvmCtx -> AdrAckCounter ;
3443
3509
int8_t datarate = MacCtx .NvmCtx -> MacParamsDefaults .ChannelsDatarate ;
3444
3510
int8_t txPower = MacCtx .NvmCtx -> MacParamsDefaults .ChannelsTxPower ;
3511
+ uint8_t nbTrans = MacCtx .ChannelsNbTransCounter ;
3445
3512
size_t macCmdsSize = 0 ;
3446
3513
3447
3514
if ( txInfo == NULL )
@@ -3450,20 +3517,20 @@ LoRaMacStatus_t LoRaMacQueryTxPossible( uint8_t size, LoRaMacTxInfo_t* txInfo )
3450
3517
}
3451
3518
3452
3519
// Setup ADR request
3453
- adrNext .Version = MacCtx .NvmCtx -> Version ;
3454
3520
adrNext .UpdateChanMask = false;
3455
3521
adrNext .AdrEnabled = MacCtx .NvmCtx -> AdrCtrlOn ;
3456
3522
adrNext .AdrAckCounter = MacCtx .NvmCtx -> AdrAckCounter ;
3457
3523
adrNext .AdrAckLimit = MacCtx .AdrAckLimit ;
3458
3524
adrNext .AdrAckDelay = MacCtx .AdrAckDelay ;
3459
3525
adrNext .Datarate = MacCtx .NvmCtx -> MacParams .ChannelsDatarate ;
3460
3526
adrNext .TxPower = MacCtx .NvmCtx -> MacParams .ChannelsTxPower ;
3527
+ adrNext .NbTrans = MacCtx .ChannelsNbTransCounter ;
3461
3528
adrNext .UplinkDwellTime = MacCtx .NvmCtx -> MacParams .UplinkDwellTime ;
3462
3529
adrNext .Region = MacCtx .NvmCtx -> Region ;
3463
3530
3464
3531
// We call the function for information purposes only. We don't want to
3465
3532
// apply the datarate, the tx power and the ADR ack counter.
3466
- LoRaMacAdrCalcNext ( & adrNext , & datarate , & txPower , & adrAckCounter );
3533
+ LoRaMacAdrCalcNext ( & adrNext , & datarate , & txPower , & nbTrans , & adrAckCounter );
3467
3534
3468
3535
txInfo -> CurrentPossiblePayloadSize = GetMaxAppPayloadWithoutFOptsLength ( datarate );
3469
3536
0 commit comments