cancel
Showing results for 
Search instead for 
Did you mean: 

LoRaWAN device join process can succeed only follow counter dev nonce when device is reset. Can this be modified ?

Candra SN.
Associate III

I have a LoRaWAN end node project with STM32CubeWL MCU Firmware Package v1.3.0.

I'm using LoRaMAC version 1.0.4. What confuses me is why my end node device can successfully join to the gateway based on the increment value of the dev nonce.

The detailed explanation is like this:

When the device is turned on for the first time, the device successfully joins the gateway on the first request and the dev nonce value is equal to 1. Then when my device is reset or turned off then turned on again, the device fails to join the gateway on the first request and the dev none value is equal to 1. But when in the second request and the dev nonce value is equal to 2, the device successfully joins to the gateway and so on like that.

Why did it happen? Is it based on the LoRaMAC version I'm using ?

What I need is that the device will attempt to successfully join to the gateway on the first request when i.e. it is reset many times, regardless of the value of the dev nonce or any other parameters. Is there a solution to my needs ?

Note: I'm using the default parameter settings from the example project LoRaWAN end node with AS923 region.

Any assistance would be greatly appreciated

5 REPLIES 5
Arya1992
Associate II

I had a similar issue with the older version of STM32CUBEWL and fixed that then, I recently upgraded to STM32CUBEWL V1.0.3 and encountered the same issue. 

The reason why your end node is not joining after resetting with Dev-Nonce 1 is that the join-server already stored the Dev-Nonce 1, according to Lorawan Specification end node cannot use the same Dev-Nonce it has used previously, the join-server will simply reject that. When the end node sends a second join request with Dev-Nounce 2, that gets accepted because Dev-Nounce is new for the join-server.

This is taken from LoRaWAN® L2 1.0.4 Specification that talks about same thing.

DevNonce is a counter starting at 0 when the end-device is initially powered up and 1435 incremented with every Join-Request. A DevNonce value SHALL never be reused for a given 1436 JoinEUI value. If the end-device can be power-cycled, then DevNonce SHALL be 1437 persistent (e.g., stored in a non-volatile memory). Resetting DevNonce without changing 1438 JoinEUI will cause the Join Server to discard the Join-Requests of the end-device. For each 1439 end-device, the Join Server keeps track of the last DevNonce value used by the end-device 1440 and ignores Join-Requests if DevNonce is not incremented.

Fix: Dev-Nounce must be stored in NVM (Non-Volatile Memory), before sending a join request, it must be read from the NVM and incremented. I don't understand why STM32CUBEWL V1.0.3 is not storing that in NVM.

Hope this helps.

SLevi.1
Associate III

I have similar issue. At which point is the nonce supposed to be stored in NVM? Upon sending any [successful or unsuccessful] join request, or only when a join request is accepted?

I am using the latest software pack, with v1.0.3 Lora, but I have changed the #define so that I am NOT using the random nonce. I see join requests with incrementing nonce numbers, but when I reset the device, the nonce goes back to 1. I've put breakpoints in the code where I think it should be storing out to flash, but they are never hit.

My code is very closely based on the endpoint example.

ngoncalves
Associate

Hello,

 

I have the same issue. It is not clear to me what this LoRa context is and how is should be used.

We tried the using the example application, and the callbacks for loading/storing data on the flash were never used during or after a join request. In, we never saw them being used at all.

 

And now we are seing that our gateway does not reply to join requests because it claims the DevNonce sent in the request is invalid.

 

So, is the LoRa context required ? Is it enough to reserve a flash section for it, or do we need to explicitely add/configure other things ?

 

Best regards,

 

 Nelson Gonçalves

Arya1992
Associate II

Hi,

This is how I modified my code. After the successful join DevNounce (and other parameters) will be stored in non-volatile memory, during the next join request (also after the power cycle reset) the last DevNounce will be read and incremented.

Cheers

 

static void OnStoreContextRequest(void *nvm, uint32_t nvm_size)
{
	/* USER CODE BEGIN OnStoreContextRequest_1 */

	/* USER CODE END OnStoreContextRequest_1 */
	/* store nvm in flash */

	if (FLASH_IF_Erase(LORAWAN_NVM_BASE_ADDRESS, FLASH_PAGE_SIZE) == FLASH_IF_OK)
	{
		APP_LOG(TS_ON, VLEVEL_M, "%s : Storing DevNonce = %d and JoinNonce %d\r\n", __func__, (*( LoRaMacNvmData_t * )nvm).Crypto.DevNonce, (*( LoRaMacNvmData_t * )nvm).Crypto.JoinNonce);
		FLASH_IF_Write(LORAWAN_NVM_BASE_ADDRESS, (const void *)nvm, nvm_size);
	}
	/* USER CODE BEGIN OnStoreContextRequest_Last */

	/* USER CODE END OnStoreContextRequest_Last */
}

static void OnRestoreContextRequest(void *nvm, uint32_t nvm_size)
{
	/* USER CODE BEGIN OnRestoreContextRequest_1 */

	/* USER CODE END OnRestoreContextRequest_1 */
	FLASH_IF_Read(nvm, LORAWAN_NVM_BASE_ADDRESS, nvm_size);
	APP_LOG(TS_ON, VLEVEL_M, "%s : Storing DevNonce = %d and JoinNonce %d\r\n", __func__, (*( LoRaMacNvmData_t * )nvm).Crypto.DevNonce, (*( LoRaMacNvmData_t * )nvm).Crypto.JoinNonce);
	/* USER CODE BEGIN OnRestoreContextRequest_Last */

	/* USER CODE END OnRestoreContextRequest_Last */
}

 

 

Hi,

 

I'm running into the same issue, where the StoreContext function (defined in lora_app.c) is never used, despite this line in LoRaWAN_Init() seemingly creating the task:

UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_LoRaStoreContextEvent), UTIL_SEQ_RFU, StoreContext);

Did you make any other modifications to get it working, aside from the one you mentioned? In my STM32CUBEWL MCU package, OnStoreContextRequest and OnRestoreContextRequest were already defined like that, except for the APP_LOG lines.