LinkADRReq with ChMaskCntl=7 ChMask=0x0000 sent to device, then fails further transmissions

Hello. Sorry if this is a newbie question about ChirpStack:

I am part of a team configuring a LoRaWAN network in South America. We are starting with a few RAK devices running as gateways, and a ChirpStack Docker container running as a network server. We had previously made successful tests with the self-contained mode of the RAK7258 (device runs its own LoRaWAN network server internally), and using OTAA for application authentication. We are using the SX126x-Arduino library with ESP32 and EBYTE E22 900M30S for the (until recently successful) tests.

On switching the RAK devices into packet forwarding mode to the ChirpStack network server, we noticed this behavior not present with standalone RAK devices: the LoRaWAN client device authenticates against the application, and successfully sends ONE application payload packet (always 10 bytes in our first example). After that, further 10-byte transmissions always fail for a while - however empty (0 byte) and small (4-byte) transmissions are successful yet. After a while (a few minutes), the device manages to transmit ONE 10-byte payload, and the cycle repeats.

On digging deeper, I noticed the following difference in LoRaWAN negotiation, in the response packet sent after the first successful payload transmission:

RAK7258 internal LoRaWAN server:
{
“MHDR”: {
“MType”: “Unconfirmed Data Down”,
“RFU”: 0,
“Major”: 0
},
“MACPayload”: {
“FHDR”: {
“DevAddr”: “0201612F”,
“FCtrl”: {
“ADR”: true,
“RFU”: 0,
“FPending”: false,
“ACK”: true,
“FOptsLen”: 5
},
“FCnt”: 3,
“FOpts”: [
{
“CID”: “LinkADRReq”,
“DataRate”: 3,
“TXPower”: 1,
“ChMask”: “0x00ff”,
“ChMaskCntl”: 0,
“NbTrans”: 0
}
]
}
},
“MIC”: “32B46B6D”
}

ChirpStack network server:
{
“MHDR”: {
“MType”: “Unconfirmed Data Down”,
“RFU”: 0,
“Major”: 0
},
“MACPayload”: {
“FHDR”: {
“DevAddr”: “0066F34D”,
“FCtrl”: {
“ADR”: true,
“RFU”: 0,
“FPending”: false,
“ACK”: true,
“FOptsLen”: 10
},
“FCnt”: 0,
“FOpts”: [
{
“CID”: “LinkADRReq”,
“DataRate”: 0,
“TXPower”: 0,
“ChMask”: “0x0000”,
“ChMaskCntl”: 7,
“NbTrans”: 0
},
{
“CID”: “LinkADRReq”,
“DataRate”: 0,
“TXPower”: 6,
“ChMask”: “0x00ff”,
“ChMaskCntl”: 0,
“NbTrans”: 1
}
]
}
},
“MIC”: “19075B0”
}

The outstanding differences for me are: the packet sent by ChirpStack has two LinkADRReq commands. In addition to the one shared by the RAK7258, there is a second one that contains ChMaskCntl=7 ChMask=0x0000 . From reading https://lora-alliance.org/wp-content/uploads/2020/11/RP_2-1.0.2.pdf, I get the impression that such a command disables all channels from 64-71, which appear to be important for LoRaWAN transmission.

In all tests, both successful and failing, the RAK device channel plan was configured in US915 region, using “channel 8 ~ channel 15, channel 65”. My boss (responsible of initial configuration of ChirpStack) in turn configured the Gateway-profile with enabled channels [8, 9, 10, 11, 12, 13, 14, 15] and no extra channels. I have tried adding channel 65 to the list, to no effect.

Is this a misconfiguration of the ChirpStack network server? Or is it an actual bug? Is it legal to have a 0x0000 mask sent for ChMaskCntl=7 ?

Additional information: I track the gateway negotiation via a MQTT server (mosquitto, using mosquitto_sub), and I notice that the “recovery” that allows the device to transmit one more packet is ALWAYS preceded by this publication:

application/2/device/15fdce284ec5b2a4/event/error {“applicationID”:“2”,“applicationName”:“TestApp”,“deviceName”:“YuboxTest”,“devEUI”:“15fdce284ec5b2a4”,“type”:“UPLINK_FCNT_RETRANSMISSION”,“error”:“frame-counter did not increment”,“fCnt”:27}

UPDATE: after studying the situation more deeply, I found the following:

  • ChMaskCntl=7 ChMask=0x0000 is indeed illegal. This command should not have been sent. However,
  • The chirpstack-docker project (which my boss used to configure the setup) has a configuration bug: the enabled channels must include the proper channel from the 64-71 range for a correct sub-band configuration, but the example configurations fail to do this. This has been reported: https://github.com/brocaar/chirpstack-docker/issues/42
  • The channel list from the gateway-profile configuration does absolutely nothing if the gateway simply does not speak the concentratord protocol with the ChirpStack suite. For us, this means such profiles have no effect (this should be more clear in the configuration and in the web GUI itself).

After adding the proper channel 65 to our enabled-chanel list, the test setup now works correctly. However, using gateways with 16-channel subband support requires setting up multiple network servers, each with a configuration variant that will be used by at least one gateway.

I believe it is valid. What ChirpStack does (in one atomic operation):

  • It disables all the channels of the device, ChMaskCntl=7 ChMask=0x0000 is the easiest way of doing so, instead of iterating over all the blocks
  • I then enables the channels in enabled_uplink_channels (chirpstack-network-server.toml)

Make sure that all these settings are aligned. In other words, make sure that ChirpStack sends the correct channel-mask to your devices and that the gateways are configured to listen on these frequencies.

Sorry, I used the wrong term. What I actually meant is not that the command is somehow not spec-compliant. What I meant is that the command was issued as a result of a broken configuration and the consequence was failure of communication until the device recovered or rebooted. For now our problem is solved by fixing the misconfiguration.