Relax frame-counter mode & receiving duplicate messages


I finally get around to dig a little bit on the why I receive multiple messages from the same uplink.

application/1/node/0044b20000000a04/rx {"applicationID":"1","applicationName":"","nodeName":"LoPy_A04","devEUI":"0044b20000000a04","rxInfo":[{"mac":"ac1dbeef00000002","time":"2017-09-07T19:18:37.299913Z","rssi":-112,"loRaSNR":-4.2,"name":"GW002","latitude":45.85282,"longitude":8.79437,"altitude":668}],"txInfo":{"frequency":868500000,"dataRate":{"modulation":"LORA","bandwidth":125,"spreadFactor":7},"adr":false,"codeRate":"4/5"},"fCnt":173,"fPort":2,"data":"nWgsQ1gAVwA="}
application/1/node/0044b20000000a04/rx {"applicationID":"1","applicationName":"","nodeName":"LoPy_A04","devEUI":"0044b20000000a04","rxInfo":[{"mac":"ac1dbeef00000003","time":"2017-09-07T19:18:37.299915Z","rssi":-85,"loRaSNR":7,"name":"GW003","latitude":45.78469,"longitude":8.77047,"altitude":349}],"txInfo":{"frequency":868500000,"dataRate":{"modulation":"LORA","bandwidth":125,"spreadFactor":7},"adr":false,"codeRate":"4/5"},"fCnt":173,"fPort":2,"data":"nWgsQ1gAVwA="}

The exact same message is arrived at two different gateway at a slightly different time (2 micro seconds I believe).

However, I do receive the message twice.

Where should I look to understand what is going on?

I had a look in the source code and I am not sure how this line: works.
It seems the same mechanism adopted here:

However, there is an extra parenthesis.
The extra parenthesis looks weird to me, especially if we consider that this code:

package main

import (

func main() {
	a, err := redis.String(("ciao"))

Doesn’t compile with:

# command-line-arguments
./main.go:9: not enough arguments in call to redis.String

I believe that either I am missing something extremelly obvious or there is some kind of typo in the source code…

However, there is an extra parenthesis.

Actually, I think they are redundant. It might be an artefact from some refactoring or shuffling code around. Please note that redis.String(("ciao")) is never going to work. This function has the following signature reply interface{}, err error (which is returned by the c.Do() method).

Although these extra parentheses are redundant, I don’t think they cause any issue. See the following example:

Question: are you using the relax frame-counter mode?

I was too tired yesterday :sweat_smile:

Yes I am using the relax frame counter.

I expect the following is happening:

  1. GW1 sends PHYPayload to LoRa Server
  2. LoRa Server starts the de-duplication process and waits 200ms (DEDUPLICATION_DELAY) for new frames
  3. During the de-duplication only the frame from GW1 was collected and forwarded to LoRa App Server
  4. GW2 sends PHYPayload to LoRa Server (note that it might have a higher network latency, thus LoRa Server received this frame after 2 completed).
  5. Normally LoRa Server would reject this frame, but since the relax frame-counter mode is turned on, it ignores that the FCnt was not incremented, thus accepts the frame and restart the de-duplication process (basically 2 & 3).

This is the drawback of the relax frame-counter mode. When you want to be secure and don’t want to receive duplicated frames and want to be safe against replay attacks, don’t use the relax frame-counter mode.

The “time” key that I see in the application/…/rx payload (inside rxInfo) what does it refer to?

At when the radio packet is been received from the physical gateway?

In this case the quick solution would be to increase the DEDUPLICATION_DELAY

The “time” key that I see in the application/…/rx payload (inside rxInfo) what does it refer to?

The time when the package was received (GPS time of gateway, only set when available). See:

Please note that by default RX1 is 1 second after transmission. Increasing DEDUPLICATION_DELAY means LoRa Server will wait longer during the de-duplication process, meaning there is less time for scheduling the downlink. You might be careful with this, especially when there is a high latency between the network-server and your gateway. Or you need to increase the RX1 delay so that you have more margin.

Simplified example: by default you have 1000 ms for the downlink. When your gateway has a 300 ms latency to the the network-server, there is 400 ms left for LoRa Server to respond (uplink 300 ms + downlink 300 ms). Now LoRa Server will wait 200 ms for the de-duplication, so you have a margin of 200 ms. So increasing this too much means you’ll never be able to schedule the downlink in time.


Humm, an interesting trade-off…

Clearly the best would be to not relax the frame counter.

Thanks for the tips :smile:

Hello @brocaar, hello @brocaar

i have a following question on your post.
you say relax frame-counter mode should not be used. my question…

how to disable / enable this mode? i cant find it anywhere. or is this the “disable frame counter validation” per sensor? if this is checked, relax frame-counter mode is used?

thanks for the answert.

It is under the device configuration, see “Disable frame-counter validation”

thank you - i changed this for one of my devices…
–> Disable frame-counter validation is uncheckt now:

but still receaving the same uplink with the same fcnt nr twice. do i need to rejoin the device? or should it work without rejoining?

Hello, I have the same problem, I did change the the frame-counter validation on my device, but I still receive duplicated data.

My device can’t rejoin for the moment so how can I change this option for my device it seems that the option was not taken into account ?

Any advice ?