Clarifiation of txinfo object in an /rx message

I just want to be sure I’m interpreting this correctly. The txinfo object in an /rx message contains the details on what transmission settings were used by the device, right?

Yes, the txInfo contains the TX related meta-data (frequency, data-rate etc). The rxInfo contains the meta-data how the transmission was received, which is unique per receiving gateway.

Yes, that make perfect sense. To dig a little deeper, can anything be inferred by the order of items in the rxInfo array? Such as, are they ordered in relative “signal quality” order, where the first gateway in the array is the one with the best quality and is thus the preferred downlink gateway? If so, how this “signal quality” calculated?

There is a sorting applied within LoRa Server, but this is not intentionally exposed as sorted. It is better to assume the list is unsorted and to apply your own sorting if needed.

OK. That’s fine. But I’m still curious about the logic you’re using to determine the “best” downlink gateway (assuming it’s based on “best” uplink quality). Can you describe that or point me to the code that does it?

This is the logic (https://github.com/brocaar/loraserver/blob/master/internal/models/packets.go#L22):

// BySignalStrength implements sort.Interface for []gw.UplinkRXInfo
// based on signal strength.
type BySignalStrength []*gw.UplinkRXInfo

func (s BySignalStrength) Len() int {
	return len(s)
}

func (s BySignalStrength) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func (s BySignalStrength) Less(i, j int) bool {
	// in case SNR is equal
	if s[i].LoraSnr == s[j].LoraSnr {
		return s[i].Rssi > s[j].Rssi
	}

	// in case the SNR > maxSNRForSort
	if s[i].LoraSnr > maxSNRForSort && s[j].LoraSnr > maxSNRForSort {
		return s[i].Rssi > s[j].Rssi
	}

	return s[i].LoraSnr > s[j].LoraSnr
}