Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to latest STM32CubeWL 1.3.1 #50

Merged
merged 7 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/STM32CubeWL/LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
| CMSIS | ARM Limited | Apache-2.0 |
| CMSIS Device | ARM Limited - STMicroelectronics | Apache-2.0 |
| STM32WL HAL | STMicroelectronics | BSD-3-Clause |
| BSP NUCLEO-WL55JC | STMicroelectronics | BSD-3-Clause |
| STM32WLxx_Nucleo | STMicroelectronics | BSD-3-Clause |
| B-WL5M-SUBG | STMicroelectronics | BSD-3-Clause |
| BSP Components | STMicroelectronics | BSD-3-Clause |
| FreeRTOS kernel | Amazon.com, Inc. or its affiliates | MIT |
Expand Down
62 changes: 62 additions & 0 deletions src/STM32CubeWL/LoRaWAN/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,68 @@ Please refer to [Releases pre-certification-results](https://github.com/Lora-net

## [Unreleased]

## [4.7.0] - 2022-12-09

### General

- Release based on "LoRaWAN specification 1.0.4" and "LoRaWAN specification 1.1.0 + FCntDwn ERRATA" with "LoRaWAN Regional Parameters 2-1.0.3"
- GitHub reported issues corrections.

### Known limitations

- SAMR34 platform does not implement NVM storage functionality. This is a requirement for LoRaWAN versions greater or equal to 1.0.4.
No work on this subject is forseen by the maintainers. Implementation proposals are welcome.

### Added

- Trigger NVM update on `MacGroup2.DutyCycleOn` change
- Configure radio sync word upon state restoration from NVM
- Added missing return status initialization for Class A
- Added a check for `GroupId` in order to avoid out of bounds access
- Make LBT RSSI free channel threshold and carrier sense time (CST) parameters configurable
- Signal NVM data change in `LoRaMacMc*` functions
- Teach `LoRaMacIsBusy` return false if the MAC is stopped
- Added support for new release of ARIB STD-T108 Ver1.4 under AS923 region
- Support LoRaWAN 1.1 with ATECC608A/B secure element
- Added a function to reset the stack internal state machine
- Added an option for MAC commands to verify against an explicit confirmation
- Added a check to verify that `SystemMaxRxError` provided value is in the range 0..500 ms

### Changed

- Updated regions implementation to regional parameters RP2-1.0.3
- Move AdrAckLimit and AdrAckDelay to NVM `MacGroup2`
- Refactored and improved the way the duty-cycle is managed

### Fixed

- Fixed class B multicast handling in `LoRaMacClassBProcessMulticastSlot()`
- Restore `RegionGroup2` in `RestoreNvmData`
- Fix a duty cycle related deadlock in `ScheduleTx`
- Fixed where `LastDownFCnt` update takes place for LoRaWAN 1.1.x
- Fixes for class C activation and deactivation
- Don't `memset` the TX/RX buffer when radio is set to receive mode
- Fixed usage of wrong API for general purpose keys
- Fixed and refactored JoinReq, `ReJoinType0Req`, `ReJoinType1Req`, `ReJoinType2Req` handling
- Fixed Rx windows timer handling
- Fixed FUOTA fragmentation implementation
- Fixed time credits check as proposed
- Fixed potential buffer overflow in `ProcessRadioRxDone` - [Security](###security)
- Applied the proposed fix for the CRC check of empty `struct`
- Fixed inconsistent handling of undefined callbacks
- Fixed `HardFault_Handler` for Cortex-M0 targets
- Fixed ABP join handling to be similar to OTAA join handling
- Fixed issue with RX2 data rate in case of 0x0F for `RxParamSetupReq` and `JoinAccept`

### Removed

- Removed useless `FOptsLen` filed check
- Removed unused `ACTIVE_REGION` pre-processing check

### Security

- Security breach found by Simon Worner(@SWW13) please refer to security advisory - [security advisory - CVE-2022-39274](https://github.com/Lora-net/LoRaMac-node/security/advisories/GHSA-7vv8-73pc-63c2)

## [4.6.0] - 2022-01-11

### General
Expand Down
148 changes: 137 additions & 11 deletions src/STM32CubeWL/LoRaWAN/Mac/LoRaMac.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@
*/
#define ADR_ACK_COUNTER_MAX 0xFFFFFFFF

/*!
* Delay required to simulate an ABP join like an OTAA join
*/
#define ABP_JOIN_PENDING_DELAY_MS 10

#if defined(__ICCARM__)
#ifndef __NO_INIT
#define __NO_INIT __no_init
Expand All @@ -119,14 +124,15 @@ static const uint8_t LoRaMacMaxEirpTable[] = { 8, 10, 12, 13, 14, 16, 18, 20, 21
*/
enum eLoRaMacState
{
LORAMAC_IDLE = 0x00000000,
LORAMAC_STOPPED = 0x00000001,
LORAMAC_TX_RUNNING = 0x00000002,
LORAMAC_RX = 0x00000004,
LORAMAC_ACK_RETRY = 0x00000010,
LORAMAC_TX_DELAYED = 0x00000020,
LORAMAC_TX_CONFIG = 0x00000040,
LORAMAC_RX_ABORT = 0x00000080,
LORAMAC_IDLE = 0x00000000,
LORAMAC_STOPPED = 0x00000001,
LORAMAC_TX_RUNNING = 0x00000002,
LORAMAC_RX = 0x00000004,
LORAMAC_ACK_RETRY = 0x00000010,
LORAMAC_TX_DELAYED = 0x00000020,
LORAMAC_TX_CONFIG = 0x00000040,
LORAMAC_RX_ABORT = 0x00000080,
LORAMAC_ABP_JOIN_PENDING = 0x00000100,
};

/*
Expand Down Expand Up @@ -314,6 +320,10 @@ typedef struct sLoRaMacCtx
* Start time of the response timeout
*/
TimerTime_t ResponseTimeoutStartTime;
/*
* Timer required to simulate an ABP join like an OTAA join
*/
TimerEvent_t AbpJoinPendingTimer;
#endif /* LORAMAC_VERSION */
/*!
* Buffer containing the MAC layer commands
Expand Down Expand Up @@ -1262,7 +1272,26 @@ static void ProcessRadioRxDone( void )
joinType = MLME_REJOIN_2;
}
#endif /* LORAMAC_VERSION */
#if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
if( LORAMAC_CRYPTO_SUCCESS == macCryptoStatus )
{
VerifyParams_t verifyRxDr;

if( macMsgJoinAccept.DLSettings.Bits.RX2DataRate != 0x0F )
{
verifyRxDr.DatarateParams.Datarate = macMsgJoinAccept.DLSettings.Bits.RX2DataRate;
verifyRxDr.DatarateParams.DownlinkDwellTime = Nvm.MacGroup2.MacParams.DownlinkDwellTime;
if( RegionVerify( Nvm.MacGroup2.Region, &verifyRxDr, PHY_RX_DR ) == false )
{
// MLME handling
if( LoRaMacConfirmQueueIsCmdActive( MLME_JOIN ) == true )
{
LoRaMacConfirmQueueSetStatus( LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL, MLME_JOIN );
}
break;
}
}
#else
VerifyParams_t verifyRxDr;
bool rxDrValid = false;
verifyRxDr.DatarateParams.Datarate = macMsgJoinAccept.DLSettings.Bits.RX2DataRate;
Expand All @@ -1271,6 +1300,8 @@ static void ProcessRadioRxDone( void )

if( ( LORAMAC_CRYPTO_SUCCESS == macCryptoStatus ) && ( rxDrValid == true ) )
{
#endif

// Network ID
Nvm.MacGroup2.NetID = ( uint32_t ) macMsgJoinAccept.NetID[0];
Nvm.MacGroup2.NetID |= ( ( uint32_t ) macMsgJoinAccept.NetID[1] << 8 );
Expand All @@ -1283,8 +1314,18 @@ static void ProcessRadioRxDone( void )

// DLSettings
Nvm.MacGroup2.MacParams.Rx1DrOffset = macMsgJoinAccept.DLSettings.Bits.RX1DRoffset;

#if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
// Verify if we shall assign the new datarate
if( macMsgJoinAccept.DLSettings.Bits.RX2DataRate != 0x0F )
{
#endif

Nvm.MacGroup2.MacParams.Rx2Channel.Datarate = macMsgJoinAccept.DLSettings.Bits.RX2DataRate;
Nvm.MacGroup2.MacParams.RxCChannel.Datarate = macMsgJoinAccept.DLSettings.Bits.RX2DataRate;
#if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
}
#endif

// RxDelay
Nvm.MacGroup2.MacParams.ReceiveDelay1 = macMsgJoinAccept.RxDelay;
Expand Down Expand Up @@ -1612,9 +1653,13 @@ static void ProcessRadioRxDone( void )
}

// Set the pending status
/* if( ( ( ( Nvm.MacGroup1.SrvAckRequested == true ) || ( macMsgData.FHDR.FCtrl.Bits.FPending > 0 ) ) && ( Nvm.MacGroup2.DeviceClass == CLASS_A ) ) ||
( MacCtx.McpsIndication.ResponseTimeout > 0 ) ) */
if( ( ( Nvm.MacGroup1.SrvAckRequested == true ) || ( macMsgData.FHDR.FCtrl.Bits.FPending > 0 ) ) && ( Nvm.MacGroup2.DeviceClass == CLASS_A ) )
// Fix for Class C Certification test. Re-enabled part of if condition previously removed.
if( ( ( ( Nvm.MacGroup1.SrvAckRequested == true ) || ( macMsgData.FHDR.FCtrl.Bits.FPending > 0 ) ) && ( Nvm.MacGroup2.DeviceClass == CLASS_A ) )
#if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
|| ( MacCtx.McpsIndication.ResponseTimeout > 0 )
#endif /* LORAMAC_VERSION */
)
//if( ( ( Nvm.MacGroup1.SrvAckRequested == true ) || ( macMsgData.FHDR.FCtrl.Bits.FPending > 0 ) ) && ( Nvm.MacGroup2.DeviceClass == CLASS_A ) )
{
MacCtx.McpsIndication.IsUplinkTxPending = 1;
}
Expand Down Expand Up @@ -2877,6 +2922,14 @@ static void ProcessMacCommands( uint8_t *payload, uint8_t macIndex, uint8_t comm
rxParamSetupReq.Datarate = payload[macIndex] & 0x0F;
macIndex++;

#if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
if( rxParamSetupReq.Datarate == 0x0F )
{
// Keep the current datarate
rxParamSetupReq.Datarate = Nvm.MacGroup2.MacParams.Rx2Channel.Datarate;
}
#endif

rxParamSetupReq.Frequency = ( uint32_t ) payload[macIndex++];
rxParamSetupReq.Frequency |= ( uint32_t ) payload[macIndex++] << 8;
rxParamSetupReq.Frequency |= ( uint32_t ) payload[macIndex++] << 16;
Expand Down Expand Up @@ -5734,7 +5787,18 @@ LoRaMacStatus_t LoRaMacMibSetRequestConfirm( MibRequestConfirm_t* mibSet )
}
case MIB_SYSTEM_MAX_RX_ERROR:
{
#if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
if( mibSet->Param.SystemMaxRxError <= 500 )
{ // Only apply the new value if in range 0..500 ms else keep current value.
Nvm.MacGroup2.MacParams.SystemMaxRxError = Nvm.MacGroup2.MacParamsDefaults.SystemMaxRxError = mibSet->Param.SystemMaxRxError;
}
else
{
status = LORAMAC_STATUS_PARAMETER_INVALID;
}
#else
Nvm.MacGroup2.MacParams.SystemMaxRxError = Nvm.MacGroup2.MacParamsDefaults.SystemMaxRxError = mibSet->Param.SystemMaxRxError;
#endif
break;
}
case MIB_MIN_RX_SYMBOLS:
Expand Down Expand Up @@ -6082,6 +6146,38 @@ LoRaMacStatus_t LoRaMacMcChannelSetupRxParams( AddressIdentifier_t groupID, McRx
return LORAMAC_STATUS_OK;
}

#if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
/*!
* \brief Function executed on AbpJoinPendingTimer timer event
*/
static void OnAbpJoinPendingTimerEvent( void *context )
{
MacCtx.MacState &= ~LORAMAC_ABP_JOIN_PENDING;
MacCtx.MacFlags.Bits.MacDone = 1;
OnMacProcessNotify( );
}

/*!
* \brief Start ABP join simulation
*/
static void AbpJoinPendingStart( void )
{
static bool initialized = false;

if( initialized == false )
{
initialized = true;
TimerInit( &MacCtx.AbpJoinPendingTimer, OnAbpJoinPendingTimerEvent );
}

MacCtx.MacState |= LORAMAC_ABP_JOIN_PENDING;

TimerStop( &MacCtx.AbpJoinPendingTimer );
TimerSetValue( &MacCtx.AbpJoinPendingTimer, ABP_JOIN_PENDING_DELAY_MS );
TimerStart( &MacCtx.AbpJoinPendingTimer );
}
#endif /* LORAMAC_VERSION */

LoRaMacStatus_t LoRaMacProcessMicForDatablock( uint8_t *buffer, uint32_t size, uint16_t sessionCnt, uint8_t fragIndex, uint32_t descriptor, uint32_t *mic )
{
LoRaMacCryptoStatus_t macCryptoStatus = LORAMAC_CRYPTO_ERROR;
Expand All @@ -6099,6 +6195,9 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest )
{
LoRaMacStatus_t status = LORAMAC_STATUS_SERVICE_UNKNOWN;
MlmeConfirmQueue_t queueElement;
#if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
bool isAbpJoinPending = false;
#endif /* LORAMAC_VERSION */
uint8_t macCmdPayload[2] = { 0x00, 0x00 };

if( mlmeRequest == NULL )
Expand Down Expand Up @@ -6191,6 +6290,9 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest )
queueElement.ReadyToHandle = true;
OnMacProcessNotify( );
MacCtx.MacFlags.Bits.MacDone = 1;
#if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
isAbpJoinPending = true;
#endif
status = LORAMAC_STATUS_OK;
}
#endif /* LORAMAC_VERSION */
Expand Down Expand Up @@ -6335,6 +6437,12 @@ LoRaMacStatus_t LoRaMacMlmeRequest( MlmeReq_t* mlmeRequest )
else
{
LoRaMacConfirmQueueAdd( &queueElement );
#if (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))
if( isAbpJoinPending == true )
{
AbpJoinPendingStart( );
}
#endif /* LORAMAC_VERSION */
}
return status;
}
Expand Down Expand Up @@ -6681,4 +6789,22 @@ LoRaMacStatus_t LoRaMacDeInitialization( void )
}
}

void LoRaMacReset( void )
{
// Reset state machine
MacCtx.MacState &= ~LORAMAC_TX_RUNNING;
MacCtx.MacFlags.Bits.MacDone = 1;

// Stop Timers
TimerStop( &MacCtx.TxDelayedTimer );
TimerStop( &MacCtx.RxWindowTimer1 );
TimerStop( &MacCtx.RxWindowTimer2 );

// Stop retransmissions
MacCtx.ChannelsNbTransCounter = Nvm.MacGroup2.MacParams.ChannelsNbTrans;

// Inform application layer
OnMacProcessNotify( );
}

#pragma GCC diagnostic pop
8 changes: 8 additions & 0 deletions src/STM32CubeWL/LoRaWAN/Mac/LoRaMac.h
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,14 @@ LoRaMacStatus_t LoRaMacDeInitialization( void );

LoRaMacStatus_t LoRaMacProcessMicForDatablock( uint8_t *buffer, uint32_t size, uint16_t sessionCnt, uint8_t fragIndex, uint32_t descriptor, uint32_t *mic );


/*!
* \brief Resets the internal state machine.
*
* \details Resets the internal state machine to force the MAC to finalize a procedure.
*/
void LoRaMacReset( void );

/*! \} defgroup LORAMAC */

#ifdef __cplusplus
Expand Down
2 changes: 1 addition & 1 deletion src/STM32CubeWL/LoRaWAN/Mac/Region/Region.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#include "../LoRaMacInterfaces.h"
#include "RegionVersion.h"

#if (defined( REGION_VERSION ) && (( REGION_VERSION == 0x01010003 ) || ( REGION_VERSION == 0x02010001 )))
#if (defined( REGION_VERSION ) && (( REGION_VERSION == 0x01010003 ) || ( REGION_VERSION == 0x02010001 ) || ( REGION_VERSION == 0x02010003 )))
#else
#error REGION_VERSION not valid
#endif /* REGION_VERSION */
Expand Down
10 changes: 5 additions & 5 deletions src/STM32CubeWL/LoRaWAN/Mac/Region/Region.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ typedef enum ePhyAttribute
* Acknowledgement time out.
*/
PHY_ACK_TIMEOUT,
#elif (defined( REGION_VERSION ) && ( REGION_VERSION == 0x02010001 ))
#elif (defined( REGION_VERSION ) && (( REGION_VERSION == 0x02010001 ) || ( REGION_VERSION == 0x02010003 )))
/*!
* Acknowledgement time out.
*/
Expand Down Expand Up @@ -482,7 +482,7 @@ typedef struct sInitDefaultsParams
* Pointer to region NVM group2.
*/
void* NvmGroup2;
#if (defined( REGION_VERSION ) && ( REGION_VERSION == 0x02010001 ))
#if (defined( REGION_VERSION ) && (( REGION_VERSION == 0x02010001 ) || ( REGION_VERSION == 0x02010003 )))
/*!
* Pointer to common region band storage.
*/
Expand Down Expand Up @@ -536,7 +536,7 @@ typedef union uVerifyParams
*/
typedef struct sApplyCFListParams
{
#if (defined( REGION_VERSION ) && ( REGION_VERSION == 0x02010001 ))
#if (defined( REGION_VERSION ) && (( REGION_VERSION == 0x02010001 ) || ( REGION_VERSION == 0x02010003 )))
uint8_t JoinChannel;
#endif /* REGION_VERSION */
/*!
Expand Down Expand Up @@ -613,7 +613,7 @@ typedef struct sRxConfigParams
* Sets the RX window.
*/
LoRaMacRxSlot_t RxSlot;
#if (defined( REGION_VERSION ) && ( REGION_VERSION == 0x02010001 ))
#if (defined( REGION_VERSION ) && (( REGION_VERSION == 0x02010001 ) || ( REGION_VERSION == 0x02010003 )))
/*!
* LoRaWAN Network End-Device Activation ( ACTIVATION_TYPE_NONE, ACTIVATION_TYPE_ABP
* or ACTIVATION_TYPE_OTTA )
Expand Down Expand Up @@ -653,7 +653,7 @@ typedef struct sTxConfigParams
* Frame length to setup.
*/
uint16_t PktLen;
#if (defined( REGION_VERSION ) && ( REGION_VERSION == 0x02010001 ))
#if (defined( REGION_VERSION ) && (( REGION_VERSION == 0x02010001 ) || ( REGION_VERSION == 0x02010003 )))
/*!
* LoRaWAN Network End-Device Activation ( ACTIVATION_TYPE_NONE, ACTIVATION_TYPE_ABP
* or ACTIVATION_TYPE_OTTA )
Expand Down
Loading