Skip to content

Commit 6b1e593

Browse files
committed
Set UplinkRxInfo location in case of rxpk + stat.
This is useful in case ChirpStack is configured to allow data from unknown gateways, and the UDP frame contains both a rkpk and stat payload. In this case, if the location is set in the stat payload, it can be set to the UplinkRxInfo struct.
1 parent b291ead commit 6b1e593

File tree

2 files changed

+83
-3
lines changed

2 files changed

+83
-3
lines changed

internal/backend/semtechudp/packets/push_data.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,15 @@ func (p PushDataPacket) GetUplinkFrames(skipCRCCheck bool, FakeRxInfoTime bool)
9191
}
9292

9393
if len(p.Payload.RXPK[i].RSig) == 0 {
94-
frame, err := getUplinkFrame(p.GatewayMAC, p.Payload.RXPK[i], FakeRxInfoTime)
94+
frame, err := getUplinkFrame(p.GatewayMAC, p.Payload.Stat, p.Payload.RXPK[i], FakeRxInfoTime)
9595
if err != nil {
9696
return nil, errors.Wrap(err, "backend/semtechudp/packets: get uplink frame error")
9797
}
9898
frame.RxInfo.UplinkId = uint32(p.RandomToken)
9999
frames = append(frames, frame)
100100
} else {
101101
for j := range p.Payload.RXPK[i].RSig {
102-
frame, err := getUplinkFrame(p.GatewayMAC, p.Payload.RXPK[i], FakeRxInfoTime)
102+
frame, err := getUplinkFrame(p.GatewayMAC, p.Payload.Stat, p.Payload.RXPK[i], FakeRxInfoTime)
103103
if err != nil {
104104
return nil, errors.Wrap(err, "backend/semtechudp/packets: get uplink frame error")
105105
}
@@ -127,7 +127,7 @@ func setUplinkFrameRSig(frame *gw.UplinkFrame, rxPK RXPK, rSig RSig) *gw.UplinkF
127127
return frame
128128
}
129129

130-
func getUplinkFrame(gatewayID lorawan.EUI64, rxpk RXPK, FakeRxInfoTime bool) (*gw.UplinkFrame, error) {
130+
func getUplinkFrame(gatewayID lorawan.EUI64, stat *Stat, rxpk RXPK, FakeRxInfoTime bool) (*gw.UplinkFrame, error) {
131131
frame := gw.UplinkFrame{
132132
PhyPayload: rxpk.Data,
133133
TxInfo: &gw.UplinkTxInfo{
@@ -145,6 +145,18 @@ func getUplinkFrame(gatewayID lorawan.EUI64, rxpk RXPK, FakeRxInfoTime bool) (*g
145145
},
146146
}
147147

148+
// If a Stat is present and it contains a location, immediately set the location for this uplink.
149+
// This is for example the case of Helium, where the UDP frame contains both a rxpk and stat
150+
// payload to provide additional gateway context.
151+
if stat != nil && (stat.Lati != 0 || stat.Long != 0 || stat.Alti != 0) {
152+
frame.RxInfo.Location = &common.Location{
153+
Latitude: stat.Lati,
154+
Longitude: stat.Long,
155+
Altitude: float64(stat.Alti),
156+
Source: common.LocationSource_GPS,
157+
}
158+
}
159+
148160
switch rxpk.Stat {
149161
case 1:
150162
frame.RxInfo.CrcStatus = gw.CRCStatus_CRC_OK

internal/backend/semtechudp/packets/push_data_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,74 @@ func TestGetUplinkFrame(t *testing.T) {
554554
},
555555
},
556556
},
557+
{
558+
Name: "uplink with stat (with location)",
559+
PushDataPacket: PushDataPacket{
560+
GatewayMAC: lorawan.EUI64{1, 2, 3, 4, 5, 6, 7, 8},
561+
ProtocolVersion: ProtocolVersion2,
562+
Payload: PushDataPayload{
563+
RXPK: []RXPK{
564+
{
565+
Time: &ctNow,
566+
Tmst: 1000000,
567+
Freq: 868.3,
568+
Brd: 2,
569+
Chan: 1,
570+
RFCh: 3,
571+
Stat: 1,
572+
Modu: "LORA",
573+
DatR: DatR{LoRa: "SF12BW500"},
574+
CodR: "4/5",
575+
RSSI: -60,
576+
LSNR: 5.5,
577+
Size: 5,
578+
Data: []byte{1, 2, 3, 4, 5},
579+
},
580+
},
581+
Stat: &Stat{
582+
Lati: 1.1,
583+
Long: 1.2,
584+
Alti: 10,
585+
},
586+
},
587+
},
588+
UplinkFrames: []*gw.UplinkFrame{
589+
{
590+
PhyPayload: []byte{1, 2, 3, 4, 5},
591+
TxInfo: &gw.UplinkTxInfo{
592+
Frequency: 868300000,
593+
Modulation: &gw.Modulation{
594+
Parameters: &gw.Modulation_Lora{
595+
Lora: &gw.LoraModulationInfo{
596+
Bandwidth: 500000,
597+
SpreadingFactor: 12,
598+
CodeRate: gw.CodeRate_CR_4_5,
599+
PolarizationInversion: false,
600+
},
601+
},
602+
},
603+
},
604+
RxInfo: &gw.UplinkRxInfo{
605+
GatewayId: "0102030405060708",
606+
Time: pbTime,
607+
Rssi: -60,
608+
Snr: 5.5,
609+
Channel: 1,
610+
RfChain: 3,
611+
Board: 2,
612+
Antenna: 0,
613+
Context: []byte{0x00, 0x0f, 0x42, 0x40},
614+
CrcStatus: gw.CRCStatus_CRC_OK,
615+
Location: &common.Location{
616+
Latitude: 1.1,
617+
Longitude: 1.2,
618+
Altitude: 10,
619+
Source: common.LocationSource_GPS,
620+
},
621+
},
622+
},
623+
},
624+
},
557625
}
558626

559627
for _, test := range testTable {

0 commit comments

Comments
 (0)