Skip to content

Commit

Permalink
Parse optional 'meta' in RXPK.
Browse files Browse the repository at this point in the history
The 'meta' field is not specified in PROTOCOL.TXT, but can be used by
custom packet-forwarder implementations to expose additional metadata.
  • Loading branch information
brocaar committed Dec 6, 2022
1 parent 24a8656 commit 2f0d5b7
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 19 deletions.
40 changes: 21 additions & 19 deletions internal/backend/semtechudp/packets/push_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
}

Expand Down Expand Up @@ -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.
Expand Down
62 changes: 62 additions & 0 deletions internal/backend/semtechudp/packets/push_data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 2f0d5b7

Please sign in to comment.