Lora-net / LoRaMac-node

Reference implementation and documentation of a LoRa network node.
Other
1.89k stars 1.09k forks source link

Suggestion: Handle missing ACK bits #368

Closed jamesl-dm closed 6 years ago

jamesl-dm commented 6 years ago

In LoRaMac.c, OnRadioRxDone, the ACK bit is checked:

                    // We need to reset the MacCommandsBufferIndex here, since we need
                    // to take retransmissions and repetitions into account. Error cases
                    // will be handled in function OnMacStateCheckTimerEvent.
                    if( McpsConfirm.McpsRequest == MCPS_CONFIRMED )
                    {
                        if( fCtrl.Bits.Ack == 1 )
                        {// Reset MacCommandsBufferIndex when we have received an ACK.
                            MacCommandsBufferIndex = 0;
                        }
                    }
                    else
                    {// Reset the variable if we have received any valid frame.
                        MacCommandsBufferIndex = 0;
                    }

I've noticed that on Actility network servers, if you disable downlink acknowledgements, they will still send downlinks in response to confirmed uplinks, if there are MAC commands that need to go down. But these downlinks have the ACK bit cleared. As far as I can tell, the standard requires that the bit be set, so the network server is non-compliant when it does this.

The embedded stack doesn't handle this deviation very gracefully. It retries the uplink, and doesn't respond to the MAC commands. So the MAC commands get sent over and over again, and the channel setup never completes. The mitigation in my fork of the code is to force the ACK bit on if the networks server neglects to set it when it should. This works fine in my class A code, but I'm not sure if it would be suitable for class C.

The network server really shouldn't be behaving that way in any case. But some networks advertise that they don't support confirmed uplinks (for duty cycle reasons), so I'm worried that they are implementing this by disabling the ACK bit on an Actility backend, and I want my devices to be tolerant of this fault.

gdeguillebon commented 6 years ago

Hi jamesl-dm,

LoRaWAN specification doesn’t oblige the network server to systematically send downlink ACK for all uplink confirmed frames: some frames couldn’t be sent due to duty cycle constraints, other frames might not be sent due to downlink traffic exceeding the maximum authorized traffic volume defined in the device’s ServiceProfile. Indeed, the ServiceProfile configuration defined in LoRaWAN backend interfaces document include downlink token bucket configuration parameters (DLRate, DLBucketSize and DLRatePolicy), so nothing says that the network server MUST send a downlink ACK for each uplink confirmed frame received! Therefore, Actility’s network server implementation is FULLY compliant to LoRaWAN standard.

In Actility’s ServiceProfile, the operator can define whether it authorizes downlink ACKs for uplink confirmed frames. Although we typically recommend activating downlink ACK to avoid the drawback of uplink retransmission, it is finally up to the operator to accept or not sending ACK for his devices. We already know some operators who DO NOT authorize devices that systematically use uplink confirmed frames because this mode is very costly for downlink resources which are already scarce.

Accordingly, device and application makers are strongly encouraged to do the following:

Best Regards

jamesl-dm commented 6 years ago

Hi,

In section 4.3.1.2, the standard says:

When receiving a confirmed data message, the receiver SHALL respond with a data frame that has the acknowledgment bit (ACK) set.

I realize that the response frame doesn't have to be sent, and may be lost even if it is sent. But I think the standard is saying that if something is sent, it must have the ACK bit set. If you disable downlinks for a device on an Actility server (using /AckedUplink/{devEUI} in the Mac command generator I think?), it sends downlinks without the ACK bit set, and this confuses the LoRaMac-node stack. I'm suggesting that the stack should handle this case a bit more gracefully - at least in class A mode.

I'm not sure if disabling the acks on Actility is just a testing command, or if people are going to deploy servers set up that way. But in any case, the LoRaMac-node stack has to decide what to do if it gets a downlink that doesn't have the ack bit set when it is expected to. I think it would be better to pretend the bit is set, rather than repeating transmissions and forgetting to send mac replies.

mluis1 commented 6 years ago

We think that this stack is correctly implemented and follows the specification. The stack has also successfully passed the LoRa-Alliance certification process. One of the tests that are run check this behavior.

The end-device can't assume that the network acknowledges a confirmed uplink when the server answers with a downlink without setting the ACK bit.

As noted by @jamesl-dm the specification says that if the server sends a downlink following a confirmed uplink it SHALL respond with a data frame that has the acknowledge bit (ACK) set.

If the server doesn't want to acknowledge the confirmed uplink it must not perform the downlink at all.