brocaar / chirpstack-network-server

ChirpStack Network Server is an open-source LoRaWAN network-server.
https://www.chirpstack.io
MIT License
1.49k stars 546 forks source link

LinkAdrReq command to use ChMaskCntl 5 (US915 Region) #558

Open lancepitka opened 2 years ago

lancepitka commented 2 years ago

Summary

It would be beneficial to support ChMaskCntl = 5 in LinkAdrReq commands for setting the channel mask in the end node. Using ChMaskCntl = 5, all 8 sub bands can be set with one downlink mac command. Currently Chirpstack only supports ChMaskCntl 0 to 4, where the mask for each individual channel is set in groups of 2 sub bands at a time. I suspect the reason for this is because the config file for the network server allows for individual channels to be set, opposed to entire sub bands being set.

Please see this section of the 1.0.3A Regional Parameters: image

What is the use-case?

The problem with only using ChMaskCntl 0 to 4 is it does not update the channel mask for all 8 sub bands in the end node. This is a problem when using a node with confirmed uplinks. When 8 confirmed uplinks are missed in a row (which happens easily since the typical number of retransmissions is usually 8), the node resets its channel plan back to the default of all 8 sub bands enabled.

Then when the next successful uplink makes its way to the network server, the server responds with a LinkAdrReq and sets the channel mask for only 2 sub bands. This means that only 2 sub bands are being updated, and the remaining 6 sub bands are left unchanged and enabled. This leaves the node in a permanent state where its channel mask does not align with the server, resulting in data loss and many unnecessary transmissions.

Please see my rambling post here for more information https://github.com/Lora-net/LoRaMac-node/issues/1211

Implementation description

There are a couple ways to implement this. One option would be to add a feature to enable sub bands instead of individual channels for the US915 region in the network server config file. If the user uses this setup, then it would be doable to implement ChMaskCntl = 5 in the LinkAdrReq commands.

Thanks for all of your hard work on this project Orne!

lancepitka commented 2 years ago

After reviewing this problem more, I realized the better solution is to transmit chMaskCntl=7 every time the channel mask is sent to the node. This is what happens following a join accept and is how the channel mask is set properly in the first place. But only chMaskCntl=[0...4] is used after this time which is why the full channel mask doesn't get reapplied properly after a node resets its channel plan after the missed confirmed ACK. If chMaskCntl=7 was used in every channel mask update, this problem would be eliminated.

brocaar commented 2 years ago

If you configure channels 0 - 7, then I believe the first LinkADRReq already contains chMaskCntl = 7 to turn everything off, the second LinkADRReq mac-command then contains the channels that must be enabled (0 - 7).

See for example this test-case: https://github.com/brocaar/lorawan/blob/master/band/band_us902_928_test.go#L245=

lancepitka commented 2 years ago

I have channels 8-15+65 enabled for my network (same at TTN). Here is an example of the channel plan being sent to the node (LoRaMac version 1.0.3) right after a join: image

You can see that first, channels 0-63 disabled and channel 65 is enabled using chMaskCntl=7, then channels 8-15 are enabled with chMaskCntl=0. At this point, the full channel plan is set properly on the node.

Now here is an example where the node doesn't receive the confirmed ACK for some reason. It resets its channel plan after the 8 uplink retransmissions, but the channel plan being sent after this occurance doesn't include chMaskCntl=7, leaving the node's channel plan inconsistent with the network's channel plan: image

image

brocaar commented 2 years ago

Now here is an example where the node doesn't receive the confirmed ACK for some reason. It resets its channel plan after the 8 uplink retransmissions

I'm not sure if this is expected behavior looking at the LoRaWAN specs. The NS is not aware about this channel-plan reset and thus it assumes that the device is still using the 8-15+65 channels.

lancepitka commented 2 years ago

Although the specs don't explicitly state this behavior for the network server, it could be assumed. Here are a few points for my reasoning:

brocaar commented 2 years ago

Why periodically send the linkAdrReq at all if it isn't going to include the full channel plan

The LinkADRReq command has two purposes:

  1. Setting the channel-mask
  2. Setting the data-rate / tx-power / nbtrans

On initial join (< LoRaWAN 1.0.3) or channel-reconfiguration, the NS sends in your case two LinkADRReq commands to synchronize the channel-mask.

Why periodically send the linkAdrReq

There is no periodically sending of the LinkADRReq, these mac-commands are for ADR purposes. Once the DR and tx-power is settled, the NS will no longer send LinkADRReq commands.

Since it is extremely probable for a device's confirmed uplink to go unacknowledged eventually and therefore reset its channel plan

Again, I'm not aware of the specification stating this. This is a very dangerous assumption to make. If a confirmed uplink is lost, there is no reason to directly reset the channel-plan. If your device is using ADR, then this is handled by the ADRAckReq bit.

image

lancepitka commented 2 years ago

Ah yes, looks like you are right. The official LoRaMac-node project implements the channel plan reset for v1.0.3, but it probably shouldn't. This is briefly mentioned in this issue.

In my sensors I have been commenting out the code to reset the channel plan, but if I use any 3rd party sensors based on this code, I won't be able to use confirmed uplinks. Simple enough I suppose!

Thanks for your patience!