9494 */
9595#define ADR_ACK_COUNTER_MAX 0xFFFFFFFF
9696
97+ /*!
98+ * Delay required to simulate an ABP join like an OTAA join
99+ */
100+ #define ABP_JOIN_PENDING_DELAY_MS 10
101+
97102#if defined(__ICCARM__ )
98103#ifndef __NO_INIT
99104#define __NO_INIT __no_init
@@ -119,14 +124,15 @@ static const uint8_t LoRaMacMaxEirpTable[] = { 8, 10, 12, 13, 14, 16, 18, 20, 21
119124 */
120125enum eLoRaMacState
121126{
122- LORAMAC_IDLE = 0x00000000 ,
123- LORAMAC_STOPPED = 0x00000001 ,
124- LORAMAC_TX_RUNNING = 0x00000002 ,
125- LORAMAC_RX = 0x00000004 ,
126- LORAMAC_ACK_RETRY = 0x00000010 ,
127- LORAMAC_TX_DELAYED = 0x00000020 ,
128- LORAMAC_TX_CONFIG = 0x00000040 ,
129- LORAMAC_RX_ABORT = 0x00000080 ,
127+ LORAMAC_IDLE = 0x00000000 ,
128+ LORAMAC_STOPPED = 0x00000001 ,
129+ LORAMAC_TX_RUNNING = 0x00000002 ,
130+ LORAMAC_RX = 0x00000004 ,
131+ LORAMAC_ACK_RETRY = 0x00000010 ,
132+ LORAMAC_TX_DELAYED = 0x00000020 ,
133+ LORAMAC_TX_CONFIG = 0x00000040 ,
134+ LORAMAC_RX_ABORT = 0x00000080 ,
135+ LORAMAC_ABP_JOIN_PENDING = 0x00000100 ,
130136};
131137
132138/*
@@ -314,6 +320,10 @@ typedef struct sLoRaMacCtx
314320 * Start time of the response timeout
315321 */
316322 TimerTime_t ResponseTimeoutStartTime ;
323+ /*
324+ * Timer required to simulate an ABP join like an OTAA join
325+ */
326+ TimerEvent_t AbpJoinPendingTimer ;
317327#endif /* LORAMAC_VERSION */
318328 /*!
319329 * Buffer containing the MAC layer commands
@@ -1130,11 +1140,6 @@ static void ProcessRadioRxDone( void )
11301140#endif /* LORAMAC_VERSION */
11311141 Mlme_t joinType = MLME_JOIN ;
11321142
1133- MW_LOG ( TS_ON , VLEVEL_M , "RX: " );
1134- for (size_t i = 0 ; i < RxDoneParams .Size ; ++ i )
1135- MW_LOG ( TS_ON , VLEVEL_M , "%02x" , RxDoneParams .Payload [i ]);
1136- MW_LOG ( TS_ON , VLEVEL_M , "\r\n" );
1137-
11381143#if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
11391144 LoRaMacRadioEvents .Events .RxProcessPending = 0 ;
11401145#endif /* LORAMAC_VERSION */
@@ -1262,7 +1267,26 @@ static void ProcessRadioRxDone( void )
12621267 joinType = MLME_REJOIN_2 ;
12631268 }
12641269#endif /* LORAMAC_VERSION */
1270+ #if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
1271+ if ( LORAMAC_CRYPTO_SUCCESS == macCryptoStatus )
1272+ {
1273+ VerifyParams_t verifyRxDr ;
12651274
1275+ if ( macMsgJoinAccept .DLSettings .Bits .RX2DataRate != 0x0F )
1276+ {
1277+ verifyRxDr .DatarateParams .Datarate = macMsgJoinAccept .DLSettings .Bits .RX2DataRate ;
1278+ verifyRxDr .DatarateParams .DownlinkDwellTime = Nvm .MacGroup2 .MacParams .DownlinkDwellTime ;
1279+ if ( RegionVerify ( Nvm .MacGroup2 .Region , & verifyRxDr , PHY_RX_DR ) == false )
1280+ {
1281+ // MLME handling
1282+ if ( LoRaMacConfirmQueueIsCmdActive ( MLME_JOIN ) == true )
1283+ {
1284+ LoRaMacConfirmQueueSetStatus ( LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL , MLME_JOIN );
1285+ }
1286+ break ;
1287+ }
1288+ }
1289+ #else
12661290 VerifyParams_t verifyRxDr ;
12671291 bool rxDrValid = false;
12681292 verifyRxDr .DatarateParams .Datarate = macMsgJoinAccept .DLSettings .Bits .RX2DataRate ;
@@ -1271,6 +1295,8 @@ static void ProcessRadioRxDone( void )
12711295
12721296 if ( ( LORAMAC_CRYPTO_SUCCESS == macCryptoStatus ) && ( rxDrValid == true ) )
12731297 {
1298+ #endif
1299+
12741300 // Network ID
12751301 Nvm .MacGroup2 .NetID = ( uint32_t ) macMsgJoinAccept .NetID [0 ];
12761302 Nvm .MacGroup2 .NetID |= ( ( uint32_t ) macMsgJoinAccept .NetID [1 ] << 8 );
@@ -1283,8 +1309,18 @@ static void ProcessRadioRxDone( void )
12831309
12841310 // DLSettings
12851311 Nvm .MacGroup2 .MacParams .Rx1DrOffset = macMsgJoinAccept .DLSettings .Bits .RX1DRoffset ;
1312+
1313+ #if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
1314+ // Verify if we shall assign the new datarate
1315+ if ( macMsgJoinAccept .DLSettings .Bits .RX2DataRate != 0x0F )
1316+ {
1317+ #endif
1318+
12861319 Nvm .MacGroup2 .MacParams .Rx2Channel .Datarate = macMsgJoinAccept .DLSettings .Bits .RX2DataRate ;
12871320 Nvm .MacGroup2 .MacParams .RxCChannel .Datarate = macMsgJoinAccept .DLSettings .Bits .RX2DataRate ;
1321+ #if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
1322+ }
1323+ #endif
12881324
12891325 // RxDelay
12901326 Nvm .MacGroup2 .MacParams .ReceiveDelay1 = macMsgJoinAccept .RxDelay ;
@@ -1612,9 +1648,10 @@ static void ProcessRadioRxDone( void )
16121648 }
16131649
16141650 // Set the pending status
1615- /* if( ( ( ( Nvm.MacGroup1.SrvAckRequested == true ) || ( macMsgData.FHDR.FCtrl.Bits.FPending > 0 ) ) && ( Nvm.MacGroup2.DeviceClass == CLASS_A ) ) ||
1616- ( MacCtx.McpsIndication.ResponseTimeout > 0 ) ) */
1617- if ( ( ( Nvm .MacGroup1 .SrvAckRequested == true ) || ( macMsgData .FHDR .FCtrl .Bits .FPending > 0 ) ) && ( Nvm .MacGroup2 .DeviceClass == CLASS_A ) )
1651+ // Fix for Class C Certification test. Re-enabled part of if condition previously removed.
1652+ if ( ( ( ( Nvm .MacGroup1 .SrvAckRequested == true ) || ( macMsgData .FHDR .FCtrl .Bits .FPending > 0 ) ) && ( Nvm .MacGroup2 .DeviceClass == CLASS_A ) ) ||
1653+ ( MacCtx .McpsIndication .ResponseTimeout > 0 ) )
1654+ //if( ( ( Nvm.MacGroup1.SrvAckRequested == true ) || ( macMsgData.FHDR.FCtrl.Bits.FPending > 0 ) ) && ( Nvm.MacGroup2.DeviceClass == CLASS_A ) )
16181655 {
16191656 MacCtx .McpsIndication .IsUplinkTxPending = 1 ;
16201657 }
@@ -2877,6 +2914,14 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm
28772914 rxParamSetupReq .Datarate = payload [macIndex ] & 0x0F ;
28782915 macIndex ++ ;
28792916
2917+ #if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
2918+ if ( rxParamSetupReq .Datarate == 0x0F )
2919+ {
2920+ // Keep the current datarate
2921+ rxParamSetupReq .Datarate = Nvm .MacGroup2 .MacParams .Rx2Channel .Datarate ;
2922+ }
2923+ #endif
2924+
28802925 rxParamSetupReq .Frequency = ( uint32_t ) payload [macIndex ++ ];
28812926 rxParamSetupReq .Frequency |= ( uint32_t ) payload [macIndex ++ ] << 8 ;
28822927 rxParamSetupReq .Frequency |= ( uint32_t ) payload [macIndex ++ ] << 16 ;
@@ -5734,7 +5779,18 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet )
57345779 }
57355780 case MIB_SYSTEM_MAX_RX_ERROR :
57365781 {
5782+ #if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
5783+ if ( mibSet -> Param .SystemMaxRxError <= 500 )
5784+ { // Only apply the new value if in range 0..500 ms else keep current value.
5785+ Nvm .MacGroup2 .MacParams .SystemMaxRxError = Nvm .MacGroup2 .MacParamsDefaults .SystemMaxRxError = mibSet -> Param .SystemMaxRxError ;
5786+ }
5787+ else
5788+ {
5789+ status = LORAMAC_STATUS_PARAMETER_INVALID ;
5790+ }
5791+ #else
57375792 Nvm .MacGroup2 .MacParams .SystemMaxRxError = Nvm .MacGroup2 .MacParamsDefaults .SystemMaxRxError = mibSet -> Param .SystemMaxRxError ;
5793+ #endif
57385794 break ;
57395795 }
57405796 case MIB_MIN_RX_SYMBOLS :
@@ -6082,6 +6138,38 @@ LoRaMacStatus_t LoRaMacMcChannelSetupRxParams( AddressIdentifier_t groupID, McRx
60826138 return LORAMAC_STATUS_OK ;
60836139}
60846140
6141+ #if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
6142+ /*!
6143+ * \brief Function executed on AbpJoinPendingTimer timer event
6144+ */
6145+ static void OnAbpJoinPendingTimerEvent ( void * context )
6146+ {
6147+ MacCtx .MacState &= ~LORAMAC_ABP_JOIN_PENDING ;
6148+ MacCtx .MacFlags .Bits .MacDone = 1 ;
6149+ OnMacProcessNotify ( );
6150+ }
6151+
6152+ /*!
6153+ * \brief Start ABP join simulation
6154+ */
6155+ static void AbpJoinPendingStart ( void )
6156+ {
6157+ static bool initialized = false;
6158+
6159+ if ( initialized == false )
6160+ {
6161+ initialized = true;
6162+ TimerInit ( & MacCtx .AbpJoinPendingTimer , OnAbpJoinPendingTimerEvent );
6163+ }
6164+
6165+ MacCtx .MacState |= LORAMAC_ABP_JOIN_PENDING ;
6166+
6167+ TimerStop ( & MacCtx .AbpJoinPendingTimer );
6168+ TimerSetValue ( & MacCtx .AbpJoinPendingTimer , ABP_JOIN_PENDING_DELAY_MS );
6169+ TimerStart ( & MacCtx .AbpJoinPendingTimer );
6170+ }
6171+ #endif /* LORAMAC_VERSION */
6172+
60856173LoRaMacStatus_t LoRaMacProcessMicForDatablock ( uint8_t * buffer , uint32_t size , uint16_t sessionCnt , uint8_t fragIndex , uint32_t descriptor , uint32_t * mic )
60866174{
60876175 LoRaMacCryptoStatus_t macCryptoStatus = LORAMAC_CRYPTO_ERROR ;
@@ -6099,6 +6187,9 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest )
60996187{
61006188 LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN ;
61016189 MlmeConfirmQueue_t queueElement ;
6190+ #if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
6191+ bool isAbpJoinPending = false;
6192+ #endif /* LORAMAC_VERSION */
61026193 uint8_t macCmdPayload [2 ] = { 0x00 , 0x00 };
61036194
61046195 if ( mlmeRequest == NULL )
@@ -6191,6 +6282,9 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest )
61916282 queueElement .ReadyToHandle = true;
61926283 OnMacProcessNotify ( );
61936284 MacCtx .MacFlags .Bits .MacDone = 1 ;
6285+ #if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
6286+ isAbpJoinPending = true;
6287+ #endif
61946288 status = LORAMAC_STATUS_OK ;
61956289 }
61966290#endif /* LORAMAC_VERSION */
@@ -6335,6 +6429,12 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest )
63356429 else
63366430 {
63376431 LoRaMacConfirmQueueAdd ( & queueElement );
6432+ #if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
6433+ if ( isAbpJoinPending == true )
6434+ {
6435+ AbpJoinPendingStart ( );
6436+ }
6437+ #endif /* LORAMAC_VERSION */
63386438 }
63396439 return status ;
63406440}
@@ -6681,4 +6781,22 @@ LoRaMacStatus_t LoRaMacDeInitialization( void )
66816781 }
66826782}
66836783
6784+ void LoRaMacReset ( void )
6785+ {
6786+ // Reset state machine
6787+ MacCtx .MacState &= ~LORAMAC_TX_RUNNING ;
6788+ MacCtx .MacFlags .Bits .MacDone = 1 ;
6789+
6790+ // Stop Timers
6791+ TimerStop ( & MacCtx .TxDelayedTimer );
6792+ TimerStop ( & MacCtx .RxWindowTimer1 );
6793+ TimerStop ( & MacCtx .RxWindowTimer2 );
6794+
6795+ // Stop retransmissions
6796+ MacCtx .ChannelsNbTransCounter = Nvm .MacGroup2 .MacParams .ChannelsNbTrans ;
6797+
6798+ // Inform application layer
6799+ OnMacProcessNotify ( );
6800+ }
6801+
66846802#pragma GCC diagnostic pop
0 commit comments