I think it may also be good to come back to the initial question asked in this thread, since we’ve learned quite a bit since 2016.
Here’s a quick summary of what Joins do:
- Every Join request contains a unique DevNonce to keep the join procedure secure
- There can be 64k (65536) different DevNonces for the same AppKey/NwkKey
- Assuming that the root keys don’t change, a node can therefore send 64k Join requests in its lifetime
- In LoRaWAN versions prior to 1.0.4, the DevNonce was random, and therefore the probability of picking a random one decreased over time. In LoRaWAN versions after 1.0.4, the DevNonce is a counter, which requires a bit of persistent memory on the device to keep track of the counter, but does not have increasing Join difficulty.
- When a Join is accepted, a new Session is started
- When the network receives the first message with the new Session, the old one is discarded
- Every Uplink and Downlink message in a Session uses a unique Frame Counter (FCnt)
- Frame Counters are 32 bits wide (allowing for 4G, 4.294.967.296, messages in a Session). Older versions of LoRaWAN used 16 bits Frame Counters (allowing for 64k, 65536, messages in a Session)
There are no real rules for when a device should transmit Join requests, but generally speaking we see devices that Join:
- When the device doesn’t have a Session
- when it is activated for the first time
- when it loses its Session on reset
- When the device thinks it has lost connection to the network
- after following the usual reconnection steps (TODO: link to guideline)
- When the application tells it to
- always good to be able to send a downlink to the device to reset it
- Periodically
- resetting a device once every week
Since most devices send Join requests when they reset, it is EXTREMELY important to avoid synchronization by always using backoff and jitter in the implementation of the Join mechanism of devices.