Skip to content

Commit

Permalink
Set UplinkRxInfo location in case of rxpk + stat.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
brocaar committed Feb 10, 2023
1 parent b291ead commit 6b1e593
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 3 deletions.
18 changes: 15 additions & 3 deletions internal/backend/semtechudp/packets/push_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,15 @@ func (p PushDataPacket) GetUplinkFrames(skipCRCCheck bool, FakeRxInfoTime bool)
}

if len(p.Payload.RXPK[i].RSig) == 0 {
frame, err := getUplinkFrame(p.GatewayMAC, p.Payload.RXPK[i], FakeRxInfoTime)
frame, err := getUplinkFrame(p.GatewayMAC, p.Payload.Stat, p.Payload.RXPK[i], FakeRxInfoTime)
if err != nil {
return nil, errors.Wrap(err, "backend/semtechudp/packets: get uplink frame error")
}
frame.RxInfo.UplinkId = uint32(p.RandomToken)
frames = append(frames, frame)
} else {
for j := range p.Payload.RXPK[i].RSig {
frame, err := getUplinkFrame(p.GatewayMAC, p.Payload.RXPK[i], FakeRxInfoTime)
frame, err := getUplinkFrame(p.GatewayMAC, p.Payload.Stat, p.Payload.RXPK[i], FakeRxInfoTime)
if err != nil {
return nil, errors.Wrap(err, "backend/semtechudp/packets: get uplink frame error")
}
Expand Down Expand Up @@ -127,7 +127,7 @@ func setUplinkFrameRSig(frame *gw.UplinkFrame, rxPK RXPK, rSig RSig) *gw.UplinkF
return frame
}

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

// If a Stat is present and it contains a location, immediately set the location for this uplink.
// This is for example the case of Helium, where the UDP frame contains both a rxpk and stat
// payload to provide additional gateway context.
if stat != nil && (stat.Lati != 0 || stat.Long != 0 || stat.Alti != 0) {
frame.RxInfo.Location = &common.Location{
Latitude: stat.Lati,
Longitude: stat.Long,
Altitude: float64(stat.Alti),
Source: common.LocationSource_GPS,
}
}

switch rxpk.Stat {
case 1:
frame.RxInfo.CrcStatus = gw.CRCStatus_CRC_OK
Expand Down
68 changes: 68 additions & 0 deletions internal/backend/semtechudp/packets/push_data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,74 @@ func TestGetUplinkFrame(t *testing.T) {
},
},
},
{
Name: "uplink with stat (with location)",
PushDataPacket: PushDataPacket{
GatewayMAC: lorawan.EUI64{1, 2, 3, 4, 5, 6, 7, 8},
ProtocolVersion: ProtocolVersion2,
Payload: PushDataPayload{
RXPK: []RXPK{
{
Time: &ctNow,
Tmst: 1000000,
Freq: 868.3,
Brd: 2,
Chan: 1,
RFCh: 3,
Stat: 1,
Modu: "LORA",
DatR: DatR{LoRa: "SF12BW500"},
CodR: "4/5",
RSSI: -60,
LSNR: 5.5,
Size: 5,
Data: []byte{1, 2, 3, 4, 5},
},
},
Stat: &Stat{
Lati: 1.1,
Long: 1.2,
Alti: 10,
},
},
},
UplinkFrames: []*gw.UplinkFrame{
{
PhyPayload: []byte{1, 2, 3, 4, 5},
TxInfo: &gw.UplinkTxInfo{
Frequency: 868300000,
Modulation: &gw.Modulation{
Parameters: &gw.Modulation_Lora{
Lora: &gw.LoraModulationInfo{
Bandwidth: 500000,
SpreadingFactor: 12,
CodeRate: gw.CodeRate_CR_4_5,
PolarizationInversion: false,
},
},
},
},
RxInfo: &gw.UplinkRxInfo{
GatewayId: "0102030405060708",
Time: pbTime,
Rssi: -60,
Snr: 5.5,
Channel: 1,
RfChain: 3,
Board: 2,
Antenna: 0,
Context: []byte{0x00, 0x0f, 0x42, 0x40},
CrcStatus: gw.CRCStatus_CRC_OK,
Location: &common.Location{
Latitude: 1.1,
Longitude: 1.2,
Altitude: 10,
Source: common.LocationSource_GPS,
},
},
},
},
},
}

for _, test := range testTable {
Expand Down

0 comments on commit 6b1e593

Please sign in to comment.