LMIC Library Always Does Unwanted Downlink

Hi @arjanvanb, I have since updated the post, showing the details of the downlinks. Hopefully this can help you assist me with this issue.

@UdLoRa, I have adjusted the post. This shows the output of the downlink details.

My answer has not changed…

(So, give us the full packet of the downlink as seen in the gateway’s Traffic page, or decipher it yourself using an online decoder. You’re looking for the contents of FCtrl and FOpts.)

1 Like

Using that online decoder here are the values of FCtrl and F0pts, which were decoded by entering the Secret NwkSKey and AppSKey. Note that this was pulled from the gateway console as the application shows the payload as not provided.

FCtrl = 8A
FOpts = 0360020071035500FF01

Below is the complete downlink payload:

Assuming hex-encoded packet

Message Type = Data
  PHYPayload = 60E01000268A00000360020071035500FF016C29CA5C

( PHYPayload = MHDR[1] | MACPayload[..] | MIC[4] )
        MHDR = 60
  MACPayload = E01000268A00000360020071035500FF01
         MIC = 6C29CA5C (from packet)
             = 6C29CA5C (expected, assuming 32 bits frame counter with MSB 0000)

( MACPayload = FHDR | FPort | FRMPayload )
        FHDR = E01000268A00000360020071035500FF01
       FPort = 
  FRMPayload = 

      ( FHDR = DevAddr[4] | FCtrl[1] | FCnt[2] | FOpts[0..15] )
     DevAddr = 260010E0 (Big Endian)
       FCtrl = 8A
        FCnt = 0000 (Big Endian)
       FOpts = 0360020071035500FF01

Message Type = Unconfirmed Data Down
   Direction = down
        FCnt = 0 (from packet, 16 bits) 
             = 0 (32 bits, assuming MSB 0x0000)
   FCtrl.ACK = false
   FCtrl.ADR = true

Correct. There is no application payload; this is only a network MAC command.

Hexadecimal 0x8A in FCtrl equals binary 0b10001010, hence indeed indicates it’s ADR (I wonder if that’s needed), and that FOptsLen = 10, so FOpts holds 10 bytes for MAC commands:

Those 10 bytes indeed start with 0x03 are actually two MAC commands, both starting with 0x03, both denoting a LinkADRReq, in which the server is requesting the device to adjust its settings:

See the LoRaWAN 1.0.1 specifications on how to decode the 10 bytes.

For AU915-928, the first 5 bytes, 0x0360020071:

  • 0x03 = LinkADRReq
  • 0x60 = DataRate_TXPower: data rate 6 (reserved for future use?); TX power 0 = 30 dBm
  • 0x0200 (LSB) = 0b00000000 00000010 (MSB) = ChMask: index 2
  • 0x71 = 0b01110001, so ChMaskCntl = 0b111: all 125 kHz OFF, and ChMask applies to channels 64 to 71, so index 2 only enables channel 65, being 917.5 - 500 kHz BW at DR4

…and the second part, 0x035500FF01:

  • 0x03 = LinkADRReq
  • 0x55 = DataRate_TXPower: data rate 5 (reserved for future use?); TX power 5 = 20 dBm
  • 0x00FF (LSB) = 0b11111111 00000000 (MSB) = ChMask: index 8 to 15
  • 0x01 = 0b00000001, so ChMaskCntl = 0b000: ChMask applies to channels 0 to 15, so index 8 to 15 enables channels 8 to 15, being 916.8 - 918.2 MHz, 125 kHz BW at DR0 to DR3

This indeed matches the 9 channels that TTN uses for AU915-928. (I’m not 100% sure I got the decoding right; I don’t understand the data rates. I should have used 1.0.2 for the decoding; see subsequent posts.)

The ADR request is needed for AU915 (and US915) because LoRaWAN 1.0.1 does not support these settings to be provided in the Join Accept response. (It does support that for EU868.) For LoRaWAN 1.0.3 and 1.1 this is supported, like the ADR documentation I quoted above already mentioned. I don’t think TTN supports 1.0.3, but it will support LoRaWAN 1.1 as of V3.

So, all as expected, and hopefully your version of LMIC will handle the ADR request. If it does, then the next uplink should include the LinkADRAns MAC command, to tell the server it handled it. So, the second uplink should show some values for FCtrl and FOpts as well.

For an EU868 example, see ADR problems - node of the same type have different ADR behaviour - #11 by arjanvanb.


@arjanvanb AU915 datarates change in 1.0.2rB to DR0-6


Nice, mystery solved!


And I guess TTN supports LoRaWAN 1.0.2 then, which still says:

2.5.4 AU915-928 JoinAccept CFList

The AU915-928 LoRaWAN does not support the use of the optional CFlist appended to the JoinAccept message. If the CFlist is not empty it is ignored by the end-device.

Whereas 1.0.3 states it’s actually supported:

2.6.4 AU915-928 JoinAccept CFList

The AU915-928 LoRaWAN supports the use of the optional CFlist appended to the JoinResp message. If the CFlist is not empty then the CFListType field SHALL contain the value one (0x01) to indicate the CFList contains a series of ChMask fields. The ChMask fields are interpreted as […]

1 Like

Okay. Thanks for the clarification. So, just that I understand, is this an expected occurrence due to the device having the initialise and setup ADR because of AU915?

There is an issue with this. Due to the fair access policy, I will infringe on the maximum number of downlinks in no time:

How then do I resolve this problem? On the surface, the downlinks are little more than a nuisance, but mean that I currently would not be able to use these nodes if I wish to follow the rules.

Also, is this the case for all LoRaWAN nodes using AU915, or is this limited to the LMIC library and it’s supported devices? I don’t recall other devices I have testing doing this, but I may be mistaken.

use another platform

Are the TTGOs, not suitable for LoRaWAN deployment then? I’m happy and already intending to transition over to another platform, however I have already invested resources and time into this hardware, meaning I don’t wish to bin what have done so far.

Seeings that quite a few people in the community use them, does that mean that users of these will always be limited to a maximum of 10 uplinks, if they choose to deep sleep, due to the device resetting?

You should only do an OTAA Join when your device unexpectedly has lost its state. During normal operation, it should keep its state between deep sleeps; see How often should a node do an OTAA Join, and is OTAA better than ABP? And if you do an OTAA Join in LoRaWAN 1.0.x many many times, you’ll eventually run into OTAA shows "Activation DevNonce not valid: already used". And for battery-powered devices, saving state is surely cheaper than re-joining many times.

So, if you save the state well, then a device only needs to do an OTAA Join once in a life time, or maybe a few times more. So, that’s one additional downlink, until LoRaWAN 1.1 is supported by TTN and the node, after which the details will be included in the OTAA Join Accept. Quite a theoretical problem, I’d say.

Also, if ever enforced, emphasis mine:

Finally, maybe TTN only sends the initial ADR when your uplink explicitly enables ADR, so you might be able to suppress it. But that would then require you to hardcode the TTN network settings into your device, creating a vendor lock-in for TTN. And ADR might actually help you save time on air for uplinks, when TTN tells the device it can use a better data rate, so I’d not disable ADR at all (unless your device does not have a fixed position).


Okay, thanks for the clarification. That makes more sense. Glad my deployment is not going to abuse the network for the occasional temperature and humidity data payload. :wink:

@BoRRoZ, I have also experienced that the network always sends a downlink confirmation message, no matter if you send a confirmed uplink or unconfirmed uplink.

@ElectronicallyE, the downlink responses are not a nuisance. First of all, they provide you with a confirmation that your uplink was received properly (I don’t know how things are in your location, but over here in the Netherlands we loose a few percent of messages due to packets colliding on the air interface). And second, the network sends useful information in the MAC commands, which your node should decode and use as directed. The ADR-info is just one example of such useful information.

For myself, I never understood this limit of 10 downlinks per day, as I have also experienced that the network confirms all uplinks with a downlink, as does the KPN network in my country by the way. It doesn’t matter if you send a confirmed or an unconfirmed uplink; there is always this reply.

That is simple maths. The gateway does not listen when it’s transmitting. (It can’t because the same antenna is used and the transmission energy would damage the receiver circuits)

So if every packet would be acked as you state gateways would have a fraction of the capacity they have now.

BTW, I know for sure correctly configured compliant LoRaWAN stacks do not get a downlink for every uplink. My gateway logs show no downlinks for >90% of the packets.

Edit: also SDR does not show anything returning when sending unconfirmed uplink.


I have the issue of uplinks downlinks with no payload since integrating TTN with AWS. It seems that the node is not ack whatever AWS IoT or TTN is sending on the port 0 uplinks.

If it was only ADR there would be only one uplink downlink and the node would respond changing the rate, but in this case the uplinks continue.

The interesting thing is that uplink downlink from TTN console also stops working. When I delete the Stack of the integration on AWS Elastic BS, this issue goes away and also the port 0 uplinks cease.

Can somebody advise how to debug what AWS IoT of the Stack is sending to get this behaviour?

Are you perhaps mixing up the terms uplink and downlink? Node transmissions are uplinks.

Yes, cslorabox, sorry about that, Downlinks keep being generated with empty payload on port 0. I have run the decoder but there are no ADR acks requests. As soon as I delete the EB Stack , they are gone.

Look for MAC commands in the fopts field

Got the following:

FOpts = 0340020071033500FF01

Message Type = Unconfirmed Data Down
Direction = down
FCnt = 0
FCtrl.ACK = false
FCtrl.ADR = true

I’ve tested this with US915 and AUS915, strange thing is that it only appears when enabling the integration (Elastic Bean template on AWS)