LMIC Frame Counter Problem
/This is a fairly exotic post, in that I doubt that many readers will be concerned how they can maintain the frame count of LoRa packets sent using the LMIC library when a device goes into deep sleep. However, I’m putting it here so that in six months time, when I probably need to do this again, I can just search the internets and find this article.
A LoRa application maintains a frame count for each connected device. This is a security measure. Any frames that that the application receives with a frame count that is lower than the highest frame count seen so far will be rejected by the application. You can turn off this frame count checking for a device, but it is not advised because it makes things a bit less secure. I’ve turned it off for my devices for now, which meant that the frame count just increases when the device is running and goes back to 0 if the device is reset.
This is kind of OK by me. I’m not overly concerned with security issues at this level. However, when I started using deep sleep mode I found that every frame that was sent had a frame counter of 0, and I really didn’t like that. The problem is caused by the way that the device is completely restarted between each transmission. This restarts the LMIC library each time, setting the frame count to 0 for every frame.
It turns out that a program can reset the LMIC frame count value by accessing a member of the LMIC object. All my program needs to do is create a variable in the RTC memory to hold the current frame count:
RTC_DATA_ATTR u4_t lmicSeqNumber = 0;
The program can then store the frame count in this variable after each LoRa message has been transmitted:
lmicSeqNumber = LMIC.seqnoUp;
Now, during the reset process after a deep sleep I can put the frame count back:
LMIC.seqnoUp = lmicSeqNumber;
I’ve tested this and it seems to work fine. The frame counter is retained when the device goes to sleep. Of course if I turn the device off the frame counter resets back to 0. I could fix this by storing the frame count in EEPROM storage but I’m not too keen on doing this because I’d have to update the value after each LoRa message and might lead to lots of writes which might “wear out” the EEPROM storage.