From 2aea7096f5036030823517fcce5a0c97021becc5 Mon Sep 17 00:00:00 2001 From: Orne Brocaar Date: Mon, 14 Feb 2022 14:33:10 +0000 Subject: [PATCH] Add LR-FHSS only and LoRa & LR-FHSS ADR algorithms. --- adr/structs.go | 1 + go.mod | 2 +- go.sum | 4 +- internal/adr/adr.go | 22 +- internal/adr/default.go | 36 +- internal/adr/default_test.go | 5 + internal/adr/lora_lr_fhss.go | 54 +++ internal/adr/lora_lr_fhss_test.go | 92 +++++ internal/adr/lr_fhss.go | 147 ++++++++ internal/adr/lr_fhss_test.go | 147 ++++++++ internal/api/ns/network_server_new_test.go | 10 +- internal/band/band.go | 4 +- internal/storage/device_session.go | 3 + internal/storage/device_session.pb.go | 381 +++++++++++---------- internal/storage/device_session.proto | 3 + internal/storage/downlink_frame.pb.go | 4 +- internal/testsuite/class_a_test.go | 138 +++++--- internal/testsuite/integration_test.go | 1 - 18 files changed, 805 insertions(+), 249 deletions(-) create mode 100644 internal/adr/lora_lr_fhss.go create mode 100644 internal/adr/lora_lr_fhss_test.go create mode 100644 internal/adr/lr_fhss.go create mode 100644 internal/adr/lr_fhss_test.go diff --git a/adr/structs.go b/adr/structs.go index d105836c..383744d0 100644 --- a/adr/structs.go +++ b/adr/structs.go @@ -83,6 +83,7 @@ type HandleResponse struct { type UplinkMetaData struct { FCnt uint32 MaxSNR float32 + MaxRSSI int32 TXPowerIndex int GatewayCount int } diff --git a/go.mod b/go.mod index d5193404..009171a6 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/Azure/azure-service-bus-go v0.9.1 github.com/NickBall/go-aes-key-wrap v0.0.0-20170929221519-1c3aa3e4dfc5 github.com/brocaar/chirpstack-api/go/v3 v3.12.5 - github.com/brocaar/lorawan v0.0.0-20211213100234-63df6954a2f3 + github.com/brocaar/lorawan v0.0.0-20220207095711-d675789e16ab github.com/eclipse/paho.mqtt.golang v1.2.0 github.com/go-redis/redis/v8 v8.8.3 github.com/gofrs/uuid v3.2.0+incompatible diff --git a/go.sum b/go.sum index 19b0134b..a2a2edf1 100644 --- a/go.sum +++ b/go.sum @@ -86,8 +86,8 @@ github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAw github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/brocaar/chirpstack-api/go/v3 v3.12.5 h1:sLV+zSZLUPnNCo2mf+gsw0ektbSiSHDvDn+RGs3ucgA= github.com/brocaar/chirpstack-api/go/v3 v3.12.5/go.mod h1:v8AWP19nOJK4rwJsr1+weDfpUc4UNLbRh8Eygn4Oh00= -github.com/brocaar/lorawan v0.0.0-20211213100234-63df6954a2f3 h1:as8V3iH+RP5ETPyjs8e2q+YF9k8AeR/8E2bmTQL6rug= -github.com/brocaar/lorawan v0.0.0-20211213100234-63df6954a2f3/go.mod h1:Vlf3gOwizqX4y3snWe/i2EqRT83HvYuwBjRu39PevW0= +github.com/brocaar/lorawan v0.0.0-20220207095711-d675789e16ab h1:sv8KWYMhLnZj7EPtZgWFl4/ZSx1f++j0Im5gYhbLuEI= +github.com/brocaar/lorawan v0.0.0-20220207095711-d675789e16ab/go.mod h1:Vlf3gOwizqX4y3snWe/i2EqRT83HvYuwBjRu39PevW0= github.com/caarlos0/ctrlc v1.0.0 h1:2DtF8GSIcajgffDFJzyG15vO+1PuBWOMUdFut7NnXhw= github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw= github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e h1:V9a67dfYqPLAvzk5hMQOXYJlZ4SLIXgyKIE+ZiHzgGQ= diff --git a/internal/adr/adr.go b/internal/adr/adr.go index b6415627..060b4fe5 100644 --- a/internal/adr/adr.go +++ b/internal/adr/adr.go @@ -17,16 +17,28 @@ var ( ) func init() { - def := &DefaultHandler{} - id, _ := def.ID() - name, _ := def.Name() + defH := &DefaultHandler{} + defID, _ := defH.ID() + defName, _ := defH.Name() + + lrFHSSH := &LRFHSSHandler{} + lrFHSSID, _ := lrFHSSH.ID() + lrFHSSName, _ := lrFHSSH.Name() + + loRaLRFHSSH := &LoRaLRFHSSHandler{} + loraLRFHSSID, _ := loRaLRFHSSH.ID() + loraLRFHSSName, _ := loRaLRFHSSH.Name() handlers = map[string]adr.Handler{ - id: def, + defID: defH, + loraLRFHSSID: loRaLRFHSSH, + lrFHSSID: lrFHSSH, } handlerNames = map[string]string{ - id: name, + defID: defName, + loraLRFHSSID: loraLRFHSSName, + lrFHSSID: lrFHSSName, } } diff --git a/internal/adr/default.go b/internal/adr/default.go index d248f08b..7623c55c 100644 --- a/internal/adr/default.go +++ b/internal/adr/default.go @@ -1,6 +1,10 @@ package adr -import "github.com/brocaar/chirpstack-network-server/v3/adr" +import ( + "github.com/brocaar/chirpstack-network-server/v3/adr" + "github.com/brocaar/chirpstack-network-server/v3/internal/band" + loraband "github.com/brocaar/lorawan/band" +) // DefaultHandler implements the default ADR handler. type DefaultHandler struct{} @@ -12,7 +16,7 @@ func (h *DefaultHandler) ID() (string, error) { // Name returns the default name. func (h *DefaultHandler) Name() (string, error) { - return "Default ADR algorithm", nil + return "Default ADR algorithm (LoRa only)", nil } // Handle handles the ADR request. @@ -30,9 +34,31 @@ func (h *DefaultHandler) Handle(req adr.HandleRequest) (adr.HandleResponse, erro return resp, nil } + // The max DR might be configured to a non LoRa (125kHz) data-rate. + // As this algorithm works on LoRa (125kHz) data-rates only, we need to + // find the max LoRa (125 kHz) data-rate. + maxDR := req.MaxDR + maxLoRaDR := 0 + enabledDRs := band.Band().GetEnabledUplinkDataRates() + for _, i := range enabledDRs { + dr, err := band.Band().GetDataRate(i) + if err != nil { + return resp, err + } + + if dr.Modulation == loraband.LoRaModulation && dr.Bandwidth == 125 { + maxLoRaDR = i + } + } + + // Reduce to max LoRa DR. + if maxDR > maxLoRaDR { + maxDR = maxLoRaDR + } + // Lower the DR only if it exceeds the max. allowed DR. - if req.DR > req.MaxDR { - resp.DR = req.MaxDR + if req.DR > maxDR { + resp.DR = maxDR } // Set the new NbTrans. @@ -50,7 +76,7 @@ func (h *DefaultHandler) Handle(req adr.HandleRequest) (adr.HandleResponse, erro return resp, nil } - resp.TxPowerIndex, resp.DR = h.getIdealTxPowerIndexAndDR(nStep, resp.TxPowerIndex, resp.DR, req.MaxTxPowerIndex, req.MaxDR) + resp.TxPowerIndex, resp.DR = h.getIdealTxPowerIndexAndDR(nStep, resp.TxPowerIndex, resp.DR, req.MaxTxPowerIndex, maxDR) return resp, nil } diff --git a/internal/adr/default_test.go b/internal/adr/default_test.go index b55cf7a9..6e4324fb 100644 --- a/internal/adr/default_test.go +++ b/internal/adr/default_test.go @@ -5,6 +5,8 @@ import ( "testing" "github.com/brocaar/chirpstack-network-server/v3/adr" + "github.com/brocaar/chirpstack-network-server/v3/internal/band" + "github.com/brocaar/chirpstack-network-server/v3/internal/test" "github.com/stretchr/testify/require" ) @@ -275,6 +277,9 @@ func TestDefaultHandler(t *testing.T) { } for _, tst := range tests { + conf := test.GetConfig() + band.Setup(conf) + t.Run(tst.name, func(t *testing.T) { assert := require.New(t) diff --git a/internal/adr/lora_lr_fhss.go b/internal/adr/lora_lr_fhss.go new file mode 100644 index 00000000..96de6c60 --- /dev/null +++ b/internal/adr/lora_lr_fhss.go @@ -0,0 +1,54 @@ +package adr + +import ( + "github.com/brocaar/chirpstack-network-server/v3/adr" + "github.com/brocaar/chirpstack-network-server/v3/internal/band" +) + +// LoRaLRFHSSHandler implements a LoRa / LR-FHSS ADR handler. +type LoRaLRFHSSHandler struct{} + +// ID returns the ID. +func (h *LoRaLRFHSSHandler) ID() (string, error) { + return "lora_lr_fhss", nil +} + +// Name returns the name. +func (h *LoRaLRFHSSHandler) Name() (string, error) { + return "LoRa & LR-FHSS ADR algorithm", nil +} + +// Handle handles the ADR request. +func (h *LoRaLRFHSSHandler) Handle(req adr.HandleRequest) (adr.HandleResponse, error) { + resp := adr.HandleResponse{ + DR: req.DR, + TxPowerIndex: req.TxPowerIndex, + NbTrans: req.NbTrans, + } + + band := band.Band() + loRaHandler := DefaultHandler{} + lrFHSSHandler := LRFHSSHandler{} + + loRaResp, err := loRaHandler.Handle(req) + if err != nil { + return resp, err + } + + loRaDR, err := band.GetDataRate(loRaResp.DR) + if err != nil { + return resp, err + } + + lrFHSSResp, err := lrFHSSHandler.Handle(req) + if err != nil { + return resp, err + } + + // For SF < 10, LoRa is a better option, for SF >= 10 use LR-FHSS. + if loRaDR.SpreadFactor < 10 { + return loRaResp, nil + } + + return lrFHSSResp, nil +} diff --git a/internal/adr/lora_lr_fhss_test.go b/internal/adr/lora_lr_fhss_test.go new file mode 100644 index 00000000..1692eff1 --- /dev/null +++ b/internal/adr/lora_lr_fhss_test.go @@ -0,0 +1,92 @@ +package adr + +import ( + "testing" + + "github.com/brocaar/chirpstack-network-server/v3/adr" + "github.com/brocaar/chirpstack-network-server/v3/internal/band" + "github.com/brocaar/chirpstack-network-server/v3/internal/test" + "github.com/stretchr/testify/require" +) + +func TestLoRaLRFHSSHandler(t *testing.T) { + h := &LoRaLRFHSSHandler{} + + t.Run("ID", func(t *testing.T) { + assert := require.New(t) + id, err := h.ID() + assert.NoError(err) + assert.Equal("lora_lr_fhss", id) + }) + + t.Run("Handle", func(t *testing.T) { + conf := test.GetConfig() + + // Add channel with LR-FHSS data-rate enabled. + conf.NetworkServer.NetworkSettings.ExtraChannels = append(conf.NetworkServer.NetworkSettings.ExtraChannels, struct { + Frequency uint32 `mapstructure:"frequency"` + MinDR int `mapstructure:"min_dr"` + MaxDR int `mapstructure:"max_dr"` + }{ + Frequency: 867300000, + MinDR: 10, + MaxDR: 11, + }) + band.Setup(conf) + + tests := []struct { + name string + request adr.HandleRequest + response adr.HandleResponse + }{ + { + name: "switch to DR 3 (LoRa)", + request: adr.HandleRequest{ + ADR: true, + DR: 0, + NbTrans: 1, + MaxDR: 11, + RequiredSNRForDR: -20, + UplinkHistory: []adr.UplinkMetaData{ + { + MaxSNR: -10, + }, + }, + }, + response: adr.HandleResponse{ + DR: 3, + NbTrans: 1, + }, + }, + { + name: "switch to DR 3 (LoRa)", + request: adr.HandleRequest{ + ADR: true, + DR: 0, + NbTrans: 3, + MaxDR: 11, + RequiredSNRForDR: -20, + UplinkHistory: []adr.UplinkMetaData{ + { + MaxSNR: -12, + }, + }, + }, + response: adr.HandleResponse{ + DR: 10, + NbTrans: 1, + }, + }, + } + + for _, tst := range tests { + t.Run(tst.name, func(t *testing.T) { + assert := require.New(t) + + resp, err := h.Handle(tst.request) + assert.NoError(err) + assert.Equal(tst.response, resp) + }) + } + }) +} diff --git a/internal/adr/lr_fhss.go b/internal/adr/lr_fhss.go new file mode 100644 index 00000000..f805e037 --- /dev/null +++ b/internal/adr/lr_fhss.go @@ -0,0 +1,147 @@ +package adr + +import ( + "math/rand" + "sort" + "time" + + "github.com/brocaar/chirpstack-network-server/v3/adr" + "github.com/brocaar/chirpstack-network-server/v3/internal/band" + loraband "github.com/brocaar/lorawan/band" +) + +// LRFHSSHandler implements a LR-FHSS only ADR handler. +type LRFHSSHandler struct{} + +// ID returns the ID. +func (h *LRFHSSHandler) ID() (string, error) { + return "lr_fhss", nil +} + +// Name returns the name. +func (h *LRFHSSHandler) Name() (string, error) { + return "LR-FHSS only ADR algorithm", nil +} + +// Handle handles the ADR request. +func (h *LRFHSSHandler) Handle(req adr.HandleRequest) (adr.HandleResponse, error) { + resp := adr.HandleResponse{ + DR: req.DR, + TxPowerIndex: req.TxPowerIndex, + NbTrans: req.NbTrans, + } + + if !req.ADR { + return resp, nil + } + + // Get the enabled uplink data-rates to find out which (if any) LR-FHSS data-rates + // are enabled. + band := band.Band() + + // Get current DR info. + dr, err := band.GetDataRate(req.DR) + if err != nil { + return resp, err + } + + // If we are already at the highest LR-FHSS data-rate, there is nothing to do. + // Note that we only differentiate between coding-rate. The OCW doesn't change + // the speed. + if dr.Modulation == loraband.LRFHSSModulation && dr.CodingRate == "4/6" { + return resp, nil + } + + // Get median RSSI. + medRSSI := getMedian(req.UplinkHistory) + + // If the median RSSI is below -130, coding-rate 1/3 is recommended, + // if we are on this coding-rate already, there is nothing to do. + if medRSSI < -130 && dr.Modulation == loraband.LRFHSSModulation && dr.CodingRate == "1/3" { + return resp, nil + } + + // Find out which LR-FHSS data-rates are enabled (note that not all + // LR-FHSS data-rates might be configured in the channel-plan). + enabledDRs := band.GetEnabledUplinkDataRates() + lrFHSSDataRates := make(map[int]loraband.DataRate) + for _, i := range enabledDRs { + dr, err := band.GetDataRate(i) + if err != nil { + return resp, err + } + + // Only get the LR-FHSS data-rates that <= MaxDR + if i <= req.MaxDR && dr.Modulation == loraband.LRFHSSModulation { + lrFHSSDataRates[i] = dr + } + } + + // There are no LR-FHSS data-rates enabled, so there is nothing to adjust. + if len(lrFHSSDataRates) == 0 { + return resp, nil + } + + // Now we decide which DRs we can use. + drs := make([]int, 0) + + // Select LR-FHSS data-rate with coding-rate 4/6 (if any available). + // Note: that for RSSI (median) < -130, coding-rate 1/3 is recommended. + // As the median is taken from the uplink history, make sure that we + // take the median from a full history table. + if medRSSI >= -130 && len(req.UplinkHistory) == 20 { + for k, v := range lrFHSSDataRates { + if v.CodingRate == "4/6" { + drs = append(drs, k) + } + } + + } + + // This either means coding-rate 1/3 must be used, or no data-rate with + // coding-rate 3/6 is enabled, and thus 1/3 is the only option. + if len(drs) == 0 { + for k, v := range lrFHSSDataRates { + if v.CodingRate == "1/3" { + drs = append(drs, k) + } + } + } + + // Sanity check + if len(drs) == 0 { + return resp, nil + } + + // Randomly select one of the available LR-FHSS data-rates. + // In case there are multiple with the same coding-rate, we take + // a random one. + s := rand.NewSource(time.Now().Unix()) + r := rand.New(s) // initialize local pseudorandom generator + resp.DR = drs[r.Intn(len(drs))] + resp.NbTrans = 1 // 1 is the recommended value + resp.TxPowerIndex = 0 // for now this ADR algorithm only controls the DR + + return resp, nil +} + +func getMedian(upMetaData []adr.UplinkMetaData) int { + // This should never occur. + if len(upMetaData) == 0 { + return 0 + } + + rssi := make([]int, 0, len(upMetaData)) + for _, up := range upMetaData { + rssi = append(rssi, int(up.MaxRSSI)) + } + sort.Ints(rssi) + m := len(rssi) / 2 + + // Odd + if len(rssi)%2 != 0 { + return rssi[m] + } + + return (rssi[m-1] + rssi[m]) / 2 +} diff --git a/internal/adr/lr_fhss_test.go b/internal/adr/lr_fhss_test.go new file mode 100644 index 00000000..6492b379 --- /dev/null +++ b/internal/adr/lr_fhss_test.go @@ -0,0 +1,147 @@ +package adr + +import ( + "testing" + + "github.com/brocaar/chirpstack-network-server/v3/adr" + "github.com/brocaar/chirpstack-network-server/v3/internal/band" + "github.com/brocaar/chirpstack-network-server/v3/internal/test" + "github.com/stretchr/testify/require" +) + +func TestLRFHSSHandler(t *testing.T) { + h := &LRFHSSHandler{} + + t.Run("ID", func(t *testing.T) { + assert := require.New(t) + id, err := h.ID() + assert.NoError(err) + assert.Equal("lr_fhss", id) + }) + + t.Run("Handle without LR-FHSS enabled", func(t *testing.T) { + assert := require.New(t) + conf := test.GetConfig() + band.Setup(conf) + + resp, err := h.Handle(adr.HandleRequest{ + ADR: true, + DR: 1, + MaxDR: 11, + }) + assert.NoError(err) + assert.Equal(adr.HandleResponse{ + DR: 1, + }, resp) + }) + + t.Run("Handle", func(t *testing.T) { + conf := test.GetConfig() + + // Add channel with LR-FHSS data-rate enabled. + conf.NetworkServer.NetworkSettings.ExtraChannels = append(conf.NetworkServer.NetworkSettings.ExtraChannels, struct { + Frequency uint32 `mapstructure:"frequency"` + MinDR int `mapstructure:"min_dr"` + MaxDR int `mapstructure:"max_dr"` + }{ + Frequency: 867300000, + MinDR: 10, + MaxDR: 11, + }) + band.Setup(conf) + + fullHistory := make([]adr.UplinkMetaData, 0, 20) + for i := 0; i < 20; i++ { + fullHistory = append(fullHistory, adr.UplinkMetaData{ + MaxRSSI: -130, + }) + } + + tests := []struct { + name string + request adr.HandleRequest + response adr.HandleResponse + }{ + { + name: "adr disabled", + request: adr.HandleRequest{ + ADR: false, + DR: 0, + NbTrans: 3, + MaxDR: 11, + UplinkHistory: []adr.UplinkMetaData{ + { + MaxRSSI: -130, + }, + }, + }, + response: adr.HandleResponse{ + DR: 0, + NbTrans: 3, + }, + }, + { + name: "max dr. prevents lr-fhss", + request: adr.HandleRequest{ + ADR: false, + DR: 0, + NbTrans: 3, + MaxDR: 5, + UplinkHistory: []adr.UplinkMetaData{ + { + MaxRSSI: -130, + }, + }, + }, + response: adr.HandleResponse{ + DR: 0, + NbTrans: 3, + }, + }, + { + name: "switch to dr 10", + request: adr.HandleRequest{ + ADR: true, + DR: 0, + NbTrans: 3, + MaxDR: 11, + UplinkHistory: []adr.UplinkMetaData{ + { + MaxRSSI: -130, + }, + }, + }, + response: adr.HandleResponse{ + DR: 10, + TxPowerIndex: 0, + NbTrans: 1, + }, + }, + { + name: "switch to dr 11", + request: adr.HandleRequest{ + ADR: true, + DR: 0, + NbTrans: 3, + MaxDR: 11, + UplinkHistory: fullHistory, + }, + response: adr.HandleResponse{ + DR: 11, + TxPowerIndex: 0, + NbTrans: 1, + }, + }, + } + + for _, tst := range tests { + t.Run(tst.name, func(t *testing.T) { + assert := require.New(t) + + resp, err := h.Handle(tst.request) + assert.NoError(err) + assert.Equal(tst.response, resp) + }) + } + }) +} diff --git a/internal/api/ns/network_server_new_test.go b/internal/api/ns/network_server_new_test.go index bffc2793..ac193ff4 100644 --- a/internal/api/ns/network_server_new_test.go +++ b/internal/api/ns/network_server_new_test.go @@ -1095,7 +1095,15 @@ func (ts *NetworkServerAPITestSuite) TestADR() { AdrAlgorithms: []*ns.ADRAlgorithm{ { Id: "default", - Name: "Default ADR algorithm", + Name: "Default ADR algorithm (LoRa only)", + }, + { + Id: "lora_lr_fhss", + Name: "LoRa & LR-FHSS ADR algorithm", + }, + { + Id: "lr_fhss", + Name: "LR-FHSS only ADR algorithm", }, }, }, resp) diff --git a/internal/band/band.go b/internal/band/band.go index 194a4f21..7344589d 100644 --- a/internal/band/band.go +++ b/internal/band/band.go @@ -20,8 +20,8 @@ func Setup(c config.Config) error { if err != nil { return errors.Wrap(err, "get band config error") } - for _, c := range config.C.NetworkServer.NetworkSettings.ExtraChannels { - if err := bandConfig.AddChannel(c.Frequency, c.MinDR, c.MaxDR); err != nil { + for _, ec := range c.NetworkServer.NetworkSettings.ExtraChannels { + if err := bandConfig.AddChannel(ec.Frequency, ec.MinDR, ec.MaxDR); err != nil { return errors.Wrap(err, "add channel error") } } diff --git a/internal/storage/device_session.go b/internal/storage/device_session.go index d72a2745..0cd80638 100644 --- a/internal/storage/device_session.go +++ b/internal/storage/device_session.go @@ -63,6 +63,7 @@ type DeviceGatewayRXInfo struct { type UplinkHistory struct { FCnt uint32 MaxSNR float64 + MaxRSSI int32 TXPowerIndex int GatewayCount int } @@ -743,6 +744,7 @@ func deviceSessionToPB(d DeviceSession) *DeviceSessionPB { MaxSnr: float32(h.MaxSNR), TxPowerIndex: uint32(h.TXPowerIndex), GatewayCount: uint32(h.GatewayCount), + MaxRssi: h.MaxRSSI, }) } @@ -856,6 +858,7 @@ func deviceSessionFromPB(d *DeviceSessionPB) DeviceSession { MaxSNR: float64(h.MaxSnr), TXPowerIndex: int(h.TxPowerIndex), GatewayCount: int(h.GatewayCount), + MaxRSSI: h.MaxRssi, }) } diff --git a/internal/storage/device_session.pb.go b/internal/storage/device_session.pb.go index d62aaba2..3d940039 100644 --- a/internal/storage/device_session.pb.go +++ b/internal/storage/device_session.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.24.0 -// protoc v3.13.0 +// protoc-gen-go v1.25.0 +// protoc v3.18.1 // source: device_session.proto package storage @@ -106,6 +106,8 @@ type DeviceSessionPBUplinkADRHistory struct { TxPowerIndex uint32 `protobuf:"varint,3,opt,name=tx_power_index,json=txPowerIndex,proto3" json:"tx_power_index,omitempty"` // Number of receiving gateways. GatewayCount uint32 `protobuf:"varint,4,opt,name=gateway_count,json=gatewayCount,proto3" json:"gateway_count,omitempty"` + // Max RSSI (of deduplicated frames received by one or multiple gateways). + MaxRssi int32 `protobuf:"varint,5,opt,name=max_rssi,json=maxRssi,proto3" json:"max_rssi,omitempty"` } func (x *DeviceSessionPBUplinkADRHistory) Reset() { @@ -168,6 +170,13 @@ func (x *DeviceSessionPBUplinkADRHistory) GetGatewayCount() uint32 { return 0 } +func (x *DeviceSessionPBUplinkADRHistory) GetMaxRssi() int32 { + if x != nil { + return x.MaxRssi + } + return 0 +} + type DeviceSessionPB struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -930,7 +939,7 @@ var file_device_session_proto_rawDesc = []byte{ 0x28, 0x0d, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x15, 0x0a, 0x06, 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x44, 0x72, 0x12, 0x15, 0x0a, 0x06, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x72, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x78, 0x44, 0x72, 0x22, 0x9a, 0x01, 0x0a, 0x1f, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x78, 0x44, 0x72, 0x22, 0xb5, 0x01, 0x0a, 0x1f, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x42, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x44, 0x52, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x13, 0x0a, 0x05, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, @@ -940,190 +949,192 @@ var file_device_session_proto_rawDesc = []byte{ 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x74, 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x67, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xf7, 0x11, 0x0a, 0x0f, 0x44, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x42, 0x12, 0x2a, 0x0a, 0x11, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, - 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x10, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x61, 0x64, 0x64, 0x72, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x64, 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x12, - 0x17, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x5f, 0x65, 0x75, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x06, 0x64, 0x65, 0x76, 0x45, 0x75, 0x69, 0x12, 0x19, 0x0a, 0x08, 0x6a, 0x6f, 0x69, 0x6e, - 0x5f, 0x65, 0x75, 0x69, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6a, 0x6f, 0x69, 0x6e, - 0x45, 0x75, 0x69, 0x12, 0x24, 0x0a, 0x0f, 0x66, 0x5f, 0x6e, 0x77, 0x6b, 0x5f, 0x73, 0x5f, 0x69, - 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x66, 0x4e, - 0x77, 0x6b, 0x53, 0x49, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0f, 0x73, 0x5f, 0x6e, - 0x77, 0x6b, 0x5f, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x4e, 0x77, 0x6b, 0x53, 0x49, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x12, - 0x21, 0x0a, 0x0d, 0x6e, 0x77, 0x6b, 0x5f, 0x73, 0x5f, 0x65, 0x6e, 0x63, 0x5f, 0x6b, 0x65, 0x79, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6e, 0x77, 0x6b, 0x53, 0x45, 0x6e, 0x63, 0x4b, - 0x65, 0x79, 0x12, 0x40, 0x0a, 0x12, 0x61, 0x70, 0x70, 0x5f, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x5f, - 0x65, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4b, 0x65, 0x79, 0x45, 0x6e, 0x76, 0x65, 0x6c, - 0x6f, 0x70, 0x65, 0x52, 0x0f, 0x61, 0x70, 0x70, 0x53, 0x4b, 0x65, 0x79, 0x45, 0x6e, 0x76, 0x65, - 0x6c, 0x6f, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x08, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x75, 0x70, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x66, 0x43, 0x6e, 0x74, 0x55, 0x70, 0x12, 0x1f, - 0x0a, 0x0c, 0x6e, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x46, 0x43, 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x12, - 0x1f, 0x0a, 0x0c, 0x61, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x18, - 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x61, 0x46, 0x43, 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, - 0x12, 0x1c, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x18, 0x27, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x66, 0x46, 0x43, 0x6e, 0x74, 0x12, 0x27, - 0x0a, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x63, 0x68, 0x65, - 0x63, 0x6b, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x43, - 0x6e, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x64, 0x65, - 0x6c, 0x61, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x72, 0x78, 0x44, 0x65, 0x6c, - 0x61, 0x79, 0x12, 0x22, 0x0a, 0x0d, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x72, 0x5f, 0x6f, 0x66, 0x66, - 0x73, 0x65, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x72, 0x78, 0x31, 0x44, 0x72, - 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x72, 0x78, 0x32, 0x5f, 0x64, 0x72, - 0x18, 0x10, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x72, 0x78, 0x32, 0x44, 0x72, 0x12, 0x23, 0x0a, - 0x0d, 0x72, 0x78, 0x32, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x11, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x72, 0x78, 0x32, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x74, 0x78, 0x50, 0x6f, - 0x77, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x72, 0x18, 0x13, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x64, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x64, 0x72, 0x18, - 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x64, 0x72, 0x12, 0x3e, 0x0a, 0x1c, 0x6d, 0x61, - 0x78, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x78, 0x5f, 0x70, - 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x18, 0x6d, 0x61, 0x78, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x54, 0x78, - 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x62, - 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6e, 0x62, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, - 0x18, 0x18, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x15, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x55, - 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x65, 0x0a, - 0x15, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x63, 0x68, - 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x19, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x73, + 0x77, 0x61, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, + 0x72, 0x73, 0x73, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, + 0x73, 0x73, 0x69, 0x22, 0xf7, 0x11, 0x0a, 0x0f, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x42, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, + 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x12, + 0x19, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x64, 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x65, + 0x76, 0x5f, 0x65, 0x75, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x65, 0x76, + 0x45, 0x75, 0x69, 0x12, 0x19, 0x0a, 0x08, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x65, 0x75, 0x69, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6a, 0x6f, 0x69, 0x6e, 0x45, 0x75, 0x69, 0x12, 0x24, + 0x0a, 0x0f, 0x66, 0x5f, 0x6e, 0x77, 0x6b, 0x5f, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x5f, 0x6b, 0x65, + 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x66, 0x4e, 0x77, 0x6b, 0x53, 0x49, 0x6e, + 0x74, 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0f, 0x73, 0x5f, 0x6e, 0x77, 0x6b, 0x5f, 0x73, 0x5f, + 0x69, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, + 0x4e, 0x77, 0x6b, 0x53, 0x49, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0d, 0x6e, 0x77, + 0x6b, 0x5f, 0x73, 0x5f, 0x65, 0x6e, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0a, 0x6e, 0x77, 0x6b, 0x53, 0x45, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x40, 0x0a, + 0x12, 0x61, 0x70, 0x70, 0x5f, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x65, 0x6e, 0x76, 0x65, 0x6c, + 0x6f, 0x70, 0x65, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x4b, 0x65, 0x79, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x52, 0x0f, + 0x61, 0x70, 0x70, 0x53, 0x4b, 0x65, 0x79, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12, + 0x18, 0x0a, 0x08, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x75, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x06, 0x66, 0x43, 0x6e, 0x74, 0x55, 0x70, 0x12, 0x1f, 0x0a, 0x0c, 0x6e, 0x5f, 0x66, + 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x09, 0x6e, 0x46, 0x43, 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x12, 0x1f, 0x0a, 0x0c, 0x61, 0x5f, + 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x61, 0x46, 0x43, 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x12, 0x1c, 0x0a, 0x0a, 0x63, + 0x6f, 0x6e, 0x66, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x18, 0x27, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x08, 0x63, 0x6f, 0x6e, 0x66, 0x46, 0x43, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x10, 0x73, 0x6b, 0x69, + 0x70, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x0d, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x43, 0x6e, 0x74, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x78, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x0e, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x72, 0x78, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x22, 0x0a, + 0x0d, 0x72, 0x78, 0x31, 0x5f, 0x64, 0x72, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x0f, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x72, 0x78, 0x31, 0x44, 0x72, 0x4f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x12, 0x15, 0x0a, 0x06, 0x72, 0x78, 0x32, 0x5f, 0x64, 0x72, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x05, 0x72, 0x78, 0x32, 0x44, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x78, 0x32, 0x5f, + 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0c, 0x72, 0x78, 0x32, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x24, 0x0a, + 0x0e, 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, + 0x12, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x74, 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x02, 0x64, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x64, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x03, 0x61, 0x64, 0x72, 0x12, 0x3e, 0x0a, 0x1c, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x18, 0x6d, 0x61, 0x78, + 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x54, 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x62, 0x5f, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6e, 0x62, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x12, 0x36, 0x0a, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x75, 0x70, 0x6c, 0x69, + 0x6e, 0x6b, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18, 0x18, 0x20, 0x03, 0x28, + 0x0d, 0x52, 0x15, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, + 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x65, 0x0a, 0x15, 0x65, 0x78, 0x74, 0x72, + 0x61, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, + 0x73, 0x18, 0x19, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, + 0x42, 0x2e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x61, + 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x65, 0x78, 0x74, 0x72, + 0x61, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x12, + 0x2f, 0x0a, 0x13, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x1a, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x12, 0x63, 0x68, + 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, + 0x12, 0x56, 0x0a, 0x12, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x61, 0x64, 0x72, 0x5f, 0x68, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x1b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x42, 0x2e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x55, 0x70, 0x6c, 0x69, - 0x6e, 0x6b, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x13, 0x65, 0x78, 0x74, 0x72, 0x61, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x61, 0x6e, - 0x6e, 0x65, 0x6c, 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, - 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x1a, 0x20, 0x03, 0x28, - 0x0d, 0x52, 0x12, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x56, 0x0a, 0x12, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, - 0x61, 0x64, 0x72, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x1b, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x42, 0x55, 0x70, 0x6c, 0x69, 0x6e, - 0x6b, 0x41, 0x44, 0x52, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x10, 0x75, 0x70, 0x6c, - 0x69, 0x6e, 0x6b, 0x41, 0x64, 0x72, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x52, 0x0a, - 0x27, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x73, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x21, - 0x6c, 0x61, 0x73, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, - 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x6c, 0x6f, 0x63, 0x6b, - 0x65, 0x64, 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, - 0x4c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, - 0x6c, 0x6f, 0x74, 0x5f, 0x6e, 0x62, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x70, 0x69, - 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x4e, 0x62, 0x12, 0x20, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, - 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x64, 0x72, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, - 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x44, 0x72, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x69, - 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, - 0x79, 0x18, 0x24, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, - 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, - 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x25, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x6d, 0x61, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x1c, 0x6d, - 0x69, 0x6e, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x78, 0x5f, - 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x26, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x18, 0x6d, 0x69, 0x6e, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x54, - 0x78, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x16, 0x72, - 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x72, 0x65, 0x6a, - 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x12, 0x3a, 0x0a, 0x1a, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x18, - 0x28, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x12, 0x38, 0x0a, - 0x19, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, - 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x15, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, - 0x61, 0x78, 0x54, 0x69, 0x6d, 0x65, 0x4e, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x65, 0x6a, 0x6f, 0x69, - 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x30, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x0c, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x30, 0x12, 0x41, 0x0a, - 0x1d, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, - 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x2b, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1a, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6a, - 0x6f, 0x69, 0x6e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x61, 0x6c, - 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x2e, 0x20, 0x01, 0x28, 0x01, 0x52, 0x11, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x41, 0x6c, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, - 0x35, 0x0a, 0x17, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x34, 0x30, 0x30, 0x6d, 0x73, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x14, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, - 0x65, 0x34, 0x30, 0x30, 0x6d, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, - 0x6e, 0x6b, 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x34, 0x30, - 0x30, 0x6d, 0x73, 0x18, 0x30, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x64, 0x6f, 0x77, 0x6e, 0x6c, + 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x42, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x44, 0x52, 0x48, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x10, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x64, + 0x72, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x52, 0x0a, 0x27, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, + 0x5f, 0x6e, 0x73, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x21, 0x6c, 0x61, 0x73, 0x74, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x73, 0x12, 0x23, 0x0a, 0x0d, + 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x21, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0c, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x4c, 0x6f, 0x63, 0x6b, 0x65, + 0x64, 0x12, 0x20, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x5f, 0x6e, + 0x62, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, + 0x74, 0x4e, 0x62, 0x12, 0x20, 0x0a, 0x0c, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, 0x6f, 0x74, + 0x5f, 0x64, 0x72, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x70, 0x69, 0x6e, 0x67, 0x53, + 0x6c, 0x6f, 0x74, 0x44, 0x72, 0x12, 0x2e, 0x0a, 0x13, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x6c, + 0x6f, 0x74, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x24, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x11, 0x70, 0x69, 0x6e, 0x67, 0x53, 0x6c, 0x6f, 0x74, 0x46, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x63, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x25, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x61, 0x63, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x1c, 0x6d, 0x69, 0x6e, 0x5f, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x78, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x18, 0x6d, 0x69, + 0x6e, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x54, 0x78, 0x50, 0x6f, 0x77, 0x65, + 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x16, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, + 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x18, 0x2c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x3a, 0x0a, 0x1a, + 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6d, + 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x16, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, + 0x61, 0x78, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x12, 0x38, 0x0a, 0x19, 0x72, 0x65, 0x6a, 0x6f, + 0x69, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x72, 0x65, 0x6a, + 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x61, 0x78, 0x54, 0x69, 0x6d, + 0x65, 0x4e, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x30, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x72, 0x65, 0x6a, 0x6f, + 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x30, 0x12, 0x41, 0x0a, 0x1d, 0x70, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x1a, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x61, 0x6c, 0x74, 0x69, 0x74, 0x75, 0x64, + 0x65, 0x18, 0x2e, 0x20, 0x01, 0x28, 0x01, 0x52, 0x11, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x41, 0x6c, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x17, 0x75, 0x70, + 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x64, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, + 0x34, 0x30, 0x30, 0x6d, 0x73, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x34, 0x30, 0x30, 0x6d, - 0x73, 0x12, 0x31, 0x0a, 0x15, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6d, 0x61, 0x78, 0x5f, - 0x65, 0x69, 0x72, 0x70, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x31, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x12, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x61, 0x78, 0x45, 0x69, 0x72, 0x70, 0x49, - 0x6e, 0x64, 0x65, 0x78, 0x12, 0x69, 0x0a, 0x17, 0x6d, 0x61, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x32, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x42, 0x2e, - 0x4d, 0x61, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x6d, 0x61, 0x63, 0x43, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x33, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x1a, 0x67, 0x0a, 0x18, 0x45, 0x78, 0x74, 0x72, 0x61, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x43, - 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x35, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, - 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x42, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x47, 0x0a, 0x19, 0x4d, 0x61, 0x63, - 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x79, 0x0a, 0x18, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x47, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x52, 0x58, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x74, 0x50, 0x42, 0x12, 0x17, - 0x0a, 0x07, 0x64, 0x65, 0x76, 0x5f, 0x65, 0x75, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x06, 0x64, 0x65, 0x76, 0x45, 0x75, 0x69, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x02, 0x64, 0x72, 0x12, 0x34, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x58, - 0x49, 0x6e, 0x66, 0x6f, 0x50, 0x42, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0xaf, 0x01, - 0x0a, 0x15, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, - 0x58, 0x49, 0x6e, 0x66, 0x6f, 0x50, 0x42, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x67, 0x61, 0x74, - 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x73, 0x73, 0x69, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x72, 0x73, 0x73, 0x69, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, - 0x72, 0x61, 0x5f, 0x73, 0x6e, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x6c, 0x6f, - 0x72, 0x61, 0x53, 0x6e, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, - 0x6e, 0x74, 0x65, 0x6e, 0x6e, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, 0x6e, - 0x74, 0x65, 0x6e, 0x6e, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, - 0xc4, 0x02, 0x0a, 0x1d, 0x50, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x52, 0x6f, 0x61, 0x6d, 0x69, - 0x6e, 0x67, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, - 0x42, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, - 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x05, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x64, 0x65, 0x76, 0x41, 0x64, - 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x5f, 0x65, 0x75, 0x69, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x65, 0x76, 0x45, 0x75, 0x69, 0x12, 0x1e, 0x0a, 0x0b, 0x6c, - 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x5f, 0x31, 0x5f, 0x31, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x09, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x31, 0x31, 0x12, 0x24, 0x0a, 0x0f, 0x66, - 0x5f, 0x6e, 0x77, 0x6b, 0x5f, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x66, 0x4e, 0x77, 0x6b, 0x53, 0x49, 0x6e, 0x74, 0x4b, 0x65, - 0x79, 0x12, 0x36, 0x0a, 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x08, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x08, 0x66, 0x5f, 0x63, - 0x6e, 0x74, 0x5f, 0x75, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x66, 0x43, 0x6e, - 0x74, 0x55, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x5f, - 0x6d, 0x69, 0x63, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x65, 0x4d, 0x69, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x12, 0x39, 0x0a, 0x19, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x64, 0x77, + 0x65, 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x34, 0x30, 0x30, 0x6d, 0x73, 0x18, 0x30, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x44, 0x77, + 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x34, 0x30, 0x30, 0x6d, 0x73, 0x12, 0x31, 0x0a, 0x15, + 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x69, 0x72, 0x70, 0x5f, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x31, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x75, 0x70, 0x6c, + 0x69, 0x6e, 0x6b, 0x4d, 0x61, 0x78, 0x45, 0x69, 0x72, 0x70, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, + 0x69, 0x0a, 0x17, 0x6d, 0x61, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x32, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x32, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x42, 0x2e, 0x4d, 0x61, 0x63, 0x43, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x6d, 0x61, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x73, + 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x33, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0a, 0x69, 0x73, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x1a, 0x67, 0x0a, 0x18, 0x45, + 0x78, 0x74, 0x72, 0x61, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, + 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x50, 0x42, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x47, 0x0a, 0x19, 0x4d, 0x61, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x79, 0x0a, + 0x18, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x58, + 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x74, 0x50, 0x42, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x65, 0x76, + 0x5f, 0x65, 0x75, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x65, 0x76, 0x45, + 0x75, 0x69, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, + 0x64, 0x72, 0x12, 0x34, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x58, 0x49, 0x6e, 0x66, 0x6f, 0x50, + 0x42, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0xaf, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x58, 0x49, 0x6e, 0x66, 0x6f, + 0x50, 0x42, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x73, 0x73, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x04, 0x72, 0x73, 0x73, 0x69, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x72, 0x61, 0x5f, 0x73, 0x6e, + 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x6c, 0x6f, 0x72, 0x61, 0x53, 0x6e, 0x72, + 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x6e, 0x74, 0x65, 0x6e, 0x6e, + 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, 0x6e, 0x74, 0x65, 0x6e, 0x6e, 0x61, + 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0xc4, 0x02, 0x0a, 0x1d, 0x50, + 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x52, 0x6f, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x42, 0x12, 0x1d, 0x0a, 0x0a, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x6e, + 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x65, 0x74, + 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x64, 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, + 0x07, 0x64, 0x65, 0x76, 0x5f, 0x65, 0x75, 0x69, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, + 0x64, 0x65, 0x76, 0x45, 0x75, 0x69, 0x12, 0x1e, 0x0a, 0x0b, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, + 0x6e, 0x5f, 0x31, 0x5f, 0x31, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6c, 0x6f, 0x72, + 0x61, 0x77, 0x61, 0x6e, 0x31, 0x31, 0x12, 0x24, 0x0a, 0x0f, 0x66, 0x5f, 0x6e, 0x77, 0x6b, 0x5f, + 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0b, 0x66, 0x4e, 0x77, 0x6b, 0x53, 0x49, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x08, + 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x6c, 0x69, 0x66, 0x65, + 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x08, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x75, 0x70, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x66, 0x43, 0x6e, 0x74, 0x55, 0x70, 0x12, 0x21, + 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, + 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/internal/storage/device_session.proto b/internal/storage/device_session.proto index aeec18bb..9afc1426 100644 --- a/internal/storage/device_session.proto +++ b/internal/storage/device_session.proto @@ -28,6 +28,9 @@ message DeviceSessionPBUplinkADRHistory { // Number of receiving gateways. uint32 gateway_count = 4; + + // Max RSSI (of deduplicated frames received by one or multiple gateways). + int32 max_rssi = 5; } message DeviceSessionPB { diff --git a/internal/storage/downlink_frame.pb.go b/internal/storage/downlink_frame.pb.go index 376cd9ef..c3150fd4 100644 --- a/internal/storage/downlink_frame.pb.go +++ b/internal/storage/downlink_frame.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.24.0 -// protoc v3.13.0 +// protoc-gen-go v1.25.0 +// protoc v3.18.1 // source: downlink_frame.proto package storage diff --git a/internal/testsuite/class_a_test.go b/internal/testsuite/class_a_test.go index 2460ce33..4ec73c29 100644 --- a/internal/testsuite/class_a_test.go +++ b/internal/testsuite/class_a_test.go @@ -22,6 +22,7 @@ import ( "github.com/brocaar/chirpstack-network-server/v3/internal/test" "github.com/brocaar/chirpstack-network-server/v3/internal/uplink" "github.com/brocaar/lorawan" + loraband "github.com/brocaar/lorawan/band" ) func init() { @@ -84,9 +85,9 @@ func (ts *ClassATestSuite) SetupSuite() { assert.NoError(helpers.SetUplinkTXInfoDataRate(&ts.TXInfo, 0, band.Band())) ts.TXInfoLRFHSS = gw.UplinkTXInfo{ - Frequency: 868100000, + Frequency: 867300000, } - assert.NoError(helpers.SetUplinkTXInfoDataRate(&ts.TXInfoLRFHSS, 8, band.Band())) + assert.NoError(helpers.SetUplinkTXInfoDataRate(&ts.TXInfoLRFHSS, 10, band.Band())) } func (ts *ClassATestSuite) TestLW10Errors() { @@ -630,49 +631,6 @@ func (ts *ClassATestSuite) TestLW10Uplink() { }), }, }, - { - Name: "unconfirmed uplink with payload using LR-FHSS dr", - DeviceSession: *ts.DeviceSession, - TXInfo: ts.TXInfoLRFHSS, - RXInfo: ts.RXInfo, - PHYPayload: lorawan.PHYPayload{ - MHDR: lorawan.MHDR{ - MType: lorawan.UnconfirmedDataUp, - Major: lorawan.LoRaWANR1, - }, - MACPayload: &lorawan.MACPayload{ - FHDR: lorawan.FHDR{ - DevAddr: ts.DeviceSession.DevAddr, - FCnt: 10, - }, - FPort: &fPortOne, - FRMPayload: []lorawan.Payload{&lorawan.DataPayload{Bytes: []byte{1, 2, 3, 4}}}, - }, - MIC: lorawan.MIC{104, 147, 35, 121}, - }, - Assert: []Assertion{ - AssertFCntUp(11), - AssertNFCntDown(5), - AssertASHandleUplinkDataRequest(as.HandleUplinkDataRequest{ - DevEui: ts.Device.DevEUI[:], - JoinEui: ts.DeviceSession.JoinEUI[:], - FCnt: 10, - FPort: 1, - Dr: 8, - TxInfo: &ts.TXInfoLRFHSS, - RxInfo: []*gw.UplinkRXInfo{&ts.RXInfo}, - Data: []byte{1, 2, 3, 4}, - }), - AssertNCHandleUplinkMetaDataRequest(nc.HandleUplinkMetaDataRequest{ - DevEui: ts.DeviceSession.DevEUI[:], - TxInfo: &ts.TXInfoLRFHSS, - RxInfo: []*gw.UplinkRXInfo{&ts.RXInfo}, - MessageType: nc.MType_UNCONFIRMED_DATA_UP, - PhyPayloadByteCount: 17, - ApplicationPayloadByteCount: 4, - }), - }, - }, { Name: "unconfirmed uplink with payload + AppSKey envelope", BeforeFunc: func(tst *ClassATest) error { @@ -982,6 +940,96 @@ func (ts *ClassATestSuite) TestLW10Uplink() { } } +func (ts *ClassATestSuite) TestLR10LRFHSSUplink() { + conf := test.GetConfig() + + // Add channel with LR-FHSS data-rate enabled. + conf.NetworkServer.NetworkSettings.ExtraChannels = append(conf.NetworkServer.NetworkSettings.ExtraChannels, struct { + Frequency uint32 `mapstructure:"frequency"` + MinDR int `mapstructure:"min_dr"` + MaxDR int `mapstructure:"max_dr"` + }{ + Frequency: 867300000, + MinDR: 10, + MaxDR: 11, + }) + band.Setup(conf) + + ts.CreateDeviceSession(storage.DeviceSession{ + MACVersion: "1.0.2", + JoinEUI: lorawan.EUI64{8, 7, 6, 5, 4, 3, 2, 1}, + DevAddr: lorawan.DevAddr{1, 2, 3, 4}, + FNwkSIntKey: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + SNwkSIntKey: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + NwkSEncKey: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + FCntUp: 8, + NFCntDown: 5, + EnabledUplinkChannels: []int{0, 1, 2, 3}, + RX2Frequency: 869525000, + ExtraUplinkChannels: map[int]loraband.Channel{ + 3: loraband.Channel{ + Frequency: 867300000, + MinDR: 10, + MaxDR: 11, + }, + }, + }) + + var fPortOne uint8 = 1 + + tests := []ClassATest{ + { + Name: "unconfirmed uplink with payload using LR-FHSS dr", + DeviceSession: *ts.DeviceSession, + TXInfo: ts.TXInfoLRFHSS, + RXInfo: ts.RXInfo, + PHYPayload: lorawan.PHYPayload{ + MHDR: lorawan.MHDR{ + MType: lorawan.UnconfirmedDataUp, + Major: lorawan.LoRaWANR1, + }, + MACPayload: &lorawan.MACPayload{ + FHDR: lorawan.FHDR{ + DevAddr: ts.DeviceSession.DevAddr, + FCnt: 10, + }, + FPort: &fPortOne, + FRMPayload: []lorawan.Payload{&lorawan.DataPayload{Bytes: []byte{1, 2, 3, 4}}}, + }, + MIC: lorawan.MIC{104, 147, 35, 121}, + }, + Assert: []Assertion{ + AssertFCntUp(11), + AssertNFCntDown(5), + AssertASHandleUplinkDataRequest(as.HandleUplinkDataRequest{ + DevEui: ts.Device.DevEUI[:], + JoinEui: ts.DeviceSession.JoinEUI[:], + FCnt: 10, + FPort: 1, + Dr: 10, + TxInfo: &ts.TXInfoLRFHSS, + RxInfo: []*gw.UplinkRXInfo{&ts.RXInfo}, + Data: []byte{1, 2, 3, 4}, + }), + AssertNCHandleUplinkMetaDataRequest(nc.HandleUplinkMetaDataRequest{ + DevEui: ts.DeviceSession.DevEUI[:], + TxInfo: &ts.TXInfoLRFHSS, + RxInfo: []*gw.UplinkRXInfo{&ts.RXInfo}, + MessageType: nc.MType_UNCONFIRMED_DATA_UP, + PhyPayloadByteCount: 17, + ApplicationPayloadByteCount: 4, + }), + }, + }, + } + + for _, tst := range tests { + ts.T().Run(tst.Name, func(t *testing.T) { + ts.AssertClassATest(t, tst) + }) + } +} + func (ts *ClassATestSuite) TestLW11Uplink() { ts.CreateDeviceSession(storage.DeviceSession{ MACVersion: "1.1.0", diff --git a/internal/testsuite/integration_test.go b/internal/testsuite/integration_test.go index 6a7c29dc..2c60fcc4 100644 --- a/internal/testsuite/integration_test.go +++ b/internal/testsuite/integration_test.go @@ -742,7 +742,6 @@ func (ts *IntegrationTestSuite) AssertDownlinkTXAckTest(t *testing.T, tst Downli func (ts *IntegrationTestSuite) initConfig() { conf := test.GetConfig() - band.Setup(conf) uplink.Setup(conf) downlink.Setup(conf)