diff --git a/internal/backend/semtechudp/packets/push_data.go b/internal/backend/semtechudp/packets/push_data.go index 10505c1c..614c7349 100644 --- a/internal/backend/semtechudp/packets/push_data.go +++ b/internal/backend/semtechudp/packets/push_data.go @@ -140,6 +140,7 @@ func getUplinkFrame(gatewayID lorawan.EUI64, rxpk RXPK, FakeRxInfoTime bool) (*g Channel: uint32(rxpk.Chan), Board: uint32(rxpk.Brd), Context: make([]byte, 4), + Metadata: rxpk.Meta, }, } @@ -344,25 +345,26 @@ type Stat struct { // RXPK contain a RF packet and associated metadata. type RXPK struct { - Time *CompactTime `json:"time"` // UTC time of pkt RX, us precision, ISO 8601 'compact' format (e.g. 2013-03-31T16:21:17.528002Z) - Tmms *int64 `json:"tmms"` // GPS time of pkt RX, number of milliseconds since 06.Jan.1980 - Tmst uint32 `json:"tmst"` // Internal timestamp of "RX finished" event (32b unsigned) - FTime *uint32 `json:"ftime"` // Fine timestamp, number of nanoseconds since last PPS [0..999999999] (Optional) - AESK uint8 `json:"aesk"` // AES key index used for encrypting fine timestamps - Chan uint8 `json:"chan"` // Concentrator "IF" channel used for RX (unsigned integer) - RFCh uint8 `json:"rfch"` // Concentrator "RF chain" used for RX (unsigned integer) - Stat int8 `json:"stat"` // CRC status: 1 = OK, -1 = fail, 0 = no CRC - Freq float64 `json:"freq"` // RX central frequency in MHz (unsigned float, Hz precision) - Brd uint32 `json:"brd"` // Concentrator board used for RX (unsigned integer) - RSSI int16 `json:"rssi"` // RSSI in dBm (signed integer, 1 dB precision) - Size uint16 `json:"size"` // RF packet payload size in bytes (unsigned integer) - DatR DatR `json:"datr"` // LoRa datarate identifier (eg. SF12BW500) || FSK datarate (unsigned, in bits per second) - Modu string `json:"modu"` // Modulation identifier "LORA" or "FSK" - CodR string `json:"codr"` // LoRa ECC coding rate identifier - LSNR float64 `json:"lsnr"` // Lora SNR ratio in dB (signed float, 0.1 dB precision) - HPW uint8 `json:"hpw"` // LR-FHSS hopping grid number of steps. - Data []byte `json:"data"` // Base64 encoded RF packet payload, padded - RSig []RSig `json:"rsig"` // Received signal information, per antenna (Optional) + Time *CompactTime `json:"time"` // UTC time of pkt RX, us precision, ISO 8601 'compact' format (e.g. 2013-03-31T16:21:17.528002Z) + Tmms *int64 `json:"tmms"` // GPS time of pkt RX, number of milliseconds since 06.Jan.1980 + Tmst uint32 `json:"tmst"` // Internal timestamp of "RX finished" event (32b unsigned) + FTime *uint32 `json:"ftime"` // Fine timestamp, number of nanoseconds since last PPS [0..999999999] (Optional) + AESK uint8 `json:"aesk"` // AES key index used for encrypting fine timestamps + Chan uint8 `json:"chan"` // Concentrator "IF" channel used for RX (unsigned integer) + RFCh uint8 `json:"rfch"` // Concentrator "RF chain" used for RX (unsigned integer) + Stat int8 `json:"stat"` // CRC status: 1 = OK, -1 = fail, 0 = no CRC + Freq float64 `json:"freq"` // RX central frequency in MHz (unsigned float, Hz precision) + Brd uint32 `json:"brd"` // Concentrator board used for RX (unsigned integer) + RSSI int16 `json:"rssi"` // RSSI in dBm (signed integer, 1 dB precision) + Size uint16 `json:"size"` // RF packet payload size in bytes (unsigned integer) + DatR DatR `json:"datr"` // LoRa datarate identifier (eg. SF12BW500) || FSK datarate (unsigned, in bits per second) + Modu string `json:"modu"` // Modulation identifier "LORA" or "FSK" + CodR string `json:"codr"` // LoRa ECC coding rate identifier + LSNR float64 `json:"lsnr"` // Lora SNR ratio in dB (signed float, 0.1 dB precision) + HPW uint8 `json:"hpw"` // LR-FHSS hopping grid number of steps. + Data []byte `json:"data"` // Base64 encoded RF packet payload, padded + RSig []RSig `json:"rsig"` // Received signal information, per antenna (Optional) + Meta map[string]string `json:"meta"` // Custom meta-data (Optional, not part of PROTOCOL.TXT) } // RSig contains the received signal information per antenna. diff --git a/internal/backend/semtechudp/packets/push_data_test.go b/internal/backend/semtechudp/packets/push_data_test.go index c43d5330..8f638e33 100644 --- a/internal/backend/semtechudp/packets/push_data_test.go +++ b/internal/backend/semtechudp/packets/push_data_test.go @@ -455,6 +455,68 @@ func TestGetUplinkFrame(t *testing.T) { }, }, }, + { + Name: "uplink with meta", + 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}, + Meta: map[string]string{ + "gateway_name": "test-gateway", + }, + }, + }, + }, + }, + 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}, + Metadata: map[string]string{ + "gateway_name": "test-gateway", + }, + }, + }, + }, + }, } for _, test := range testTable {