From d411d3bef1a1ce2e1653e586dd326b4d8e67c4ea Mon Sep 17 00:00:00 2001 From: Orne Brocaar Date: Thu, 26 Jan 2023 13:05:56 +0000 Subject: [PATCH] Update chirpstack_api + add CrcStatus field back to UplinkRxInfo. --- go.mod | 2 +- go.sum | 2 ++ internal/backend/basicstation/backend_test.go | 3 +++ .../basicstation/structs/join_request_test.go | 1 + .../basicstation/structs/radio_meta_data.go | 1 + .../structs/radio_meta_data_test.go | 3 +++ .../structs/uplink_data_frame_test.go | 3 +++ .../structs/uplink_proprietary_test.go | 1 + internal/backend/semtechudp/backend.go | 18 ++++++++++-------- internal/backend/semtechudp/backend_test.go | 1 + .../backend/semtechudp/packets/push_data.go | 13 +++++++++++-- .../semtechudp/packets/push_data_test.go | 8 +++++++- internal/config/config.go | 5 +++-- 13 files changed, 47 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 6675db9d..781473dc 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/brocaar/lorawan v0.0.0-20220207095711-d675789e16ab - github.com/chirpstack/chirpstack/api/go/v4 v4.1.0 + github.com/chirpstack/chirpstack/api/go/v4 v4.2.0 github.com/eclipse/paho.mqtt.golang v1.4.1 github.com/go-zeromq/zmq4 v0.7.0 github.com/golang-jwt/jwt/v4 v4.4.2 diff --git a/go.sum b/go.sum index 4c5f9e88..8bbd9717 100644 --- a/go.sum +++ b/go.sum @@ -101,6 +101,8 @@ github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cb github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chirpstack/chirpstack/api/go/v4 v4.1.0 h1:D3ViDwYMmB9yE050i8EbqkGkIkPz8w4NwkdbPk1iat8= github.com/chirpstack/chirpstack/api/go/v4 v4.1.0/go.mod h1:KBW7imf70O9ifrMmoFH8+dn0+MUFS1PdC5shXH7W3dI= +github.com/chirpstack/chirpstack/api/go/v4 v4.2.0 h1:XswPjMY3Pqqo4V8ZgjhL3MfDeIvmAUakZSxefLj+5U0= +github.com/chirpstack/chirpstack/api/go/v4 v4.2.0/go.mod h1:KBW7imf70O9ifrMmoFH8+dn0+MUFS1PdC5shXH7W3dI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= diff --git a/internal/backend/basicstation/backend_test.go b/internal/backend/basicstation/backend_test.go index 9eb304a1..dc65ccc7 100644 --- a/internal/backend/basicstation/backend_test.go +++ b/internal/backend/basicstation/backend_test.go @@ -183,6 +183,7 @@ func (ts *BackendTestSuite) TestUplinkDataFrame() { Rssi: 120, Snr: 5.5, Context: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, uplinkFrame)) @@ -267,6 +268,7 @@ func (ts *BackendTestSuite) TestJoinRequest() { Rssi: 120, Snr: 5.5, Context: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, uplinkFrame)) @@ -346,6 +348,7 @@ func (ts *BackendTestSuite) TestProprietaryDataFrame() { Rssi: 120, Snr: 5.5, Context: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, uplinkFrame)) diff --git a/internal/backend/basicstation/structs/join_request_test.go b/internal/backend/basicstation/structs/join_request_test.go index ce3607d2..b4a5930d 100644 --- a/internal/backend/basicstation/structs/join_request_test.go +++ b/internal/backend/basicstation/structs/join_request_test.go @@ -66,6 +66,7 @@ func TestJoinRequestToProto(t *testing.T) { Rssi: 120, Snr: 5.5, Context: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, pb) diff --git a/internal/backend/basicstation/structs/radio_meta_data.go b/internal/backend/basicstation/structs/radio_meta_data.go index cb9d6800..d2cd352f 100644 --- a/internal/backend/basicstation/structs/radio_meta_data.go +++ b/internal/backend/basicstation/structs/radio_meta_data.go @@ -74,6 +74,7 @@ func SetRadioMetaDataToProto(loraBand band.Band, gatewayID lorawan.EUI64, rmd Ra GatewayId: gatewayID.String(), Rssi: int32(rmd.UpInfo.RSSI), Snr: float32(rmd.UpInfo.SNR), + CrcStatus: gw.CRCStatus_CRC_OK, } if rxTime := rmd.UpInfo.RxTime; rxTime != 0 { diff --git a/internal/backend/basicstation/structs/radio_meta_data_test.go b/internal/backend/basicstation/structs/radio_meta_data_test.go index 653c2df9..abefb85e 100644 --- a/internal/backend/basicstation/structs/radio_meta_data_test.go +++ b/internal/backend/basicstation/structs/radio_meta_data_test.go @@ -55,6 +55,7 @@ func TestSetRadioMetaDataToProto(t *testing.T) { Rssi: 120, Snr: 5.5, Context: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, }, @@ -84,6 +85,7 @@ func TestSetRadioMetaDataToProto(t *testing.T) { GatewayId: "0102030405060708", Rssi: 120, Context: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, }, @@ -120,6 +122,7 @@ func TestSetRadioMetaDataToProto(t *testing.T) { Context: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, TimeSinceGpsEpoch: durationpb.New(5 * time.Second), Time: timeP, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, }, diff --git a/internal/backend/basicstation/structs/uplink_data_frame_test.go b/internal/backend/basicstation/structs/uplink_data_frame_test.go index edd2c63e..78c5086d 100644 --- a/internal/backend/basicstation/structs/uplink_data_frame_test.go +++ b/internal/backend/basicstation/structs/uplink_data_frame_test.go @@ -59,6 +59,7 @@ func TestUplinkDataFrameToProto(t *testing.T) { Rssi: 120, Snr: 5.5, Context: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, }, @@ -103,6 +104,7 @@ func TestUplinkDataFrameToProto(t *testing.T) { Rssi: 120, Snr: 5.5, Context: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, }, @@ -148,6 +150,7 @@ func TestUplinkDataFrameToProto(t *testing.T) { Rssi: 120, Snr: 5.5, Context: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, }, diff --git a/internal/backend/basicstation/structs/uplink_proprietary_test.go b/internal/backend/basicstation/structs/uplink_proprietary_test.go index c596b239..dd27608c 100644 --- a/internal/backend/basicstation/structs/uplink_proprietary_test.go +++ b/internal/backend/basicstation/structs/uplink_proprietary_test.go @@ -51,6 +51,7 @@ func TestUplinkProprietaryFrameToProto(t *testing.T) { Rssi: 120, Snr: 5.5, Context: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, }, diff --git a/internal/backend/semtechudp/backend.go b/internal/backend/semtechudp/backend.go index 337e4dca..14128a68 100644 --- a/internal/backend/semtechudp/backend.go +++ b/internal/backend/semtechudp/backend.go @@ -42,11 +42,12 @@ type Backend struct { udpSendChan chan udpPacket - wg sync.WaitGroup - conn *net.UDPConn - closed bool - gateways gateways - fakeRxTime bool + wg sync.WaitGroup + conn *net.UDPConn + closed bool + gateways gateways + fakeRxTime bool + skipCRCCheck bool } // NewBackend creates a new backend. @@ -68,8 +69,9 @@ func NewBackend(conf config.Config) (*Backend, error) { gateways: gateways{ gateways: make(map[lorawan.EUI64]gateway), }, - fakeRxTime: conf.Backend.SemtechUDP.FakeRxTime, - cache: cache.New(15*time.Second, 15*time.Second), + fakeRxTime: conf.Backend.SemtechUDP.FakeRxTime, + skipCRCCheck: conf.Backend.SemtechUDP.SkipCRCCheck, + cache: cache.New(15*time.Second, 15*time.Second), } go func() { @@ -468,7 +470,7 @@ func (b *Backend) handlePushData(up udpPacket) error { } // uplink frames - uplinkFrames, err := p.GetUplinkFrames(b.fakeRxTime) + uplinkFrames, err := p.GetUplinkFrames(b.skipCRCCheck, b.fakeRxTime) if err != nil { return errors.Wrap(err, "get uplink frames error") } diff --git a/internal/backend/semtechudp/backend_test.go b/internal/backend/semtechudp/backend_test.go index bed241f5..bd9de985 100644 --- a/internal/backend/semtechudp/backend_test.go +++ b/internal/backend/semtechudp/backend_test.go @@ -772,6 +772,7 @@ func (ts *BackendTestSuite) TestPushData() { Channel: 2, RfChain: 1, Context: []byte{0x2a, 0x33, 0x7a, 0xb3}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, }, diff --git a/internal/backend/semtechudp/packets/push_data.go b/internal/backend/semtechudp/packets/push_data.go index 184ddd65..9cd96616 100644 --- a/internal/backend/semtechudp/packets/push_data.go +++ b/internal/backend/semtechudp/packets/push_data.go @@ -81,12 +81,12 @@ func (p PushDataPacket) GetGatewayStats() (*gw.GatewayStats, error) { } // GetUplinkFrames returns a slice of gw.UplinkFrame. -func (p PushDataPacket) GetUplinkFrames(FakeRxInfoTime bool) ([]*gw.UplinkFrame, error) { +func (p PushDataPacket) GetUplinkFrames(skipCRCCheck bool, FakeRxInfoTime bool) ([]*gw.UplinkFrame, error) { var frames []*gw.UplinkFrame for i := range p.Payload.RXPK { // validate CRC - if p.Payload.RXPK[i].Stat != 1 { + if p.Payload.RXPK[i].Stat != 1 && !skipCRCCheck { continue } @@ -145,6 +145,15 @@ func getUplinkFrame(gatewayID lorawan.EUI64, rxpk RXPK, FakeRxInfoTime bool) (*g }, } + switch rxpk.Stat { + case 1: + frame.RxInfo.CrcStatus = gw.CRCStatus_CRC_OK + case -1: + frame.RxInfo.CrcStatus = gw.CRCStatus_BAD_CRC + default: + frame.RxInfo.CrcStatus = gw.CRCStatus_NO_CRC + } + // Context binary.BigEndian.PutUint32(frame.RxInfo.Context, rxpk.Tmst) diff --git a/internal/backend/semtechudp/packets/push_data_test.go b/internal/backend/semtechudp/packets/push_data_test.go index 4c2a5e34..4db1ecb3 100644 --- a/internal/backend/semtechudp/packets/push_data_test.go +++ b/internal/backend/semtechudp/packets/push_data_test.go @@ -271,6 +271,7 @@ func TestGetUplinkFrame(t *testing.T) { Board: 2, Antenna: 0, Context: []byte{0x00, 0x0f, 0x42, 0x40}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, }, @@ -345,6 +346,7 @@ func TestGetUplinkFrame(t *testing.T) { Board: 2, Antenna: 8, Context: []byte{0x00, 0x0f, 0x42, 0x40}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, { @@ -373,6 +375,7 @@ func TestGetUplinkFrame(t *testing.T) { Board: 2, Antenna: 9, Context: []byte{0x00, 0x0f, 0x42, 0x40}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, }, @@ -422,6 +425,7 @@ func TestGetUplinkFrame(t *testing.T) { GatewayId: "0102030405060708", Rssi: -74, Context: []byte{0x00, 0x0f, 0x42, 0x40}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, }, @@ -482,6 +486,7 @@ func TestGetUplinkFrame(t *testing.T) { Board: 2, Antenna: 0, Context: []byte{0x00, 0x0f, 0x42, 0x40}, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, }, @@ -544,6 +549,7 @@ func TestGetUplinkFrame(t *testing.T) { Metadata: map[string]string{ "gateway_name": "test-gateway", }, + CrcStatus: gw.CRCStatus_CRC_OK, }, }, }, @@ -553,7 +559,7 @@ func TestGetUplinkFrame(t *testing.T) { for _, test := range testTable { t.Run(test.Name, func(t *testing.T) { assert := require.New(t) - f, err := test.PushDataPacket.GetUplinkFrames(false) + f, err := test.PushDataPacket.GetUplinkFrames(false, false) assert.Nil(err) for _, ff := range f { diff --git a/internal/config/config.go b/internal/config/config.go index 7ca9f9a0..f7baa181 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -20,8 +20,9 @@ type Config struct { Type string `mapstructure:"type"` SemtechUDP struct { - UDPBind string `mapstructure:"udp_bind"` - FakeRxTime bool `mapstructure:"fake_rx_time"` + UDPBind string `mapstructure:"udp_bind"` + SkipCRCCheck bool `mapstructure:"skip_crc_check"` + FakeRxTime bool `mapstructure:"fake_rx_time"` } `mapstructure:"semtech_udp"` BasicStation struct {