From 7434bc63842913c2f31e8a8e29b116c00b1b9d2d Mon Sep 17 00:00:00 2001 From: Adrian-Stefan Mares Date: Fri, 25 Aug 2023 19:18:23 +0200 Subject: [PATCH] all: Add relay support to band description RPCs --- api/ttn/lorawan/v3/api.md | 17 + api/ttn/lorawan/v3/api.swagger.json | 31 + .../lorawan/v3/configuration_services.proto | 11 + pkg/band/rpc.go | 11 + pkg/band/rpc_test.go | 70 ++- pkg/ttnpb/configuration_services.pb.go | 541 ++++++++++++------ .../configuration_services.pb.paths.fm.go | 21 + .../configuration_services.pb.setters.fm.go | 85 +++ .../configuration_services.pb.validate.go | 205 +++++++ pkg/ttnpb/configuration_services_json.pb.go | 133 +++++ sdk/js/generated/api.json | 84 +++ 11 files changed, 1017 insertions(+), 192 deletions(-) diff --git a/api/ttn/lorawan/v3/api.md b/api/ttn/lorawan/v3/api.md index e68aeb9434..f4e341167b 100644 --- a/api/ttn/lorawan/v3/api.md +++ b/api/ttn/lorawan/v3/api.md @@ -144,6 +144,8 @@ - [Message `BandDescription.Channel`](#ttn.lorawan.v3.BandDescription.Channel) - [Message `BandDescription.DataRatesEntry`](#ttn.lorawan.v3.BandDescription.DataRatesEntry) - [Message `BandDescription.DwellTime`](#ttn.lorawan.v3.BandDescription.DwellTime) + - [Message `BandDescription.RelayParameters`](#ttn.lorawan.v3.BandDescription.RelayParameters) + - [Message `BandDescription.RelayParameters.RelayWORChannel`](#ttn.lorawan.v3.BandDescription.RelayParameters.RelayWORChannel) - [Message `BandDescription.Rx2Parameters`](#ttn.lorawan.v3.BandDescription.Rx2Parameters) - [Message `BandDescription.SubBandParameters`](#ttn.lorawan.v3.BandDescription.SubBandParameters) - [Message `FrequencyPlanDescription`](#ttn.lorawan.v3.FrequencyPlanDescription) @@ -2466,6 +2468,7 @@ PeerInfo | `default_max_eirp` | [`float`](#float) | | | | `default_rx2_parameters` | [`BandDescription.Rx2Parameters`](#ttn.lorawan.v3.BandDescription.Rx2Parameters) | | | | `boot_dwell_time` | [`BandDescription.DwellTime`](#ttn.lorawan.v3.BandDescription.DwellTime) | | | +| `relay` | [`BandDescription.RelayParameters`](#ttn.lorawan.v3.BandDescription.RelayParameters) | | | ### Message `BandDescription.BandDataRate` @@ -2503,6 +2506,20 @@ PeerInfo | `uplinks` | [`google.protobuf.BoolValue`](#google.protobuf.BoolValue) | | | | `downlinks` | [`google.protobuf.BoolValue`](#google.protobuf.BoolValue) | | | +### Message `BandDescription.RelayParameters` + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `wor_channels` | [`BandDescription.RelayParameters.RelayWORChannel`](#ttn.lorawan.v3.BandDescription.RelayParameters.RelayWORChannel) | repeated | | + +### Message `BandDescription.RelayParameters.RelayWORChannel` + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `frequency` | [`uint64`](#uint64) | | | +| `ack_frequency` | [`uint64`](#uint64) | | | +| `data_rate_index` | [`DataRateIndex`](#ttn.lorawan.v3.DataRateIndex) | | | + ### Message `BandDescription.Rx2Parameters` | Field | Type | Label | Description | diff --git a/api/ttn/lorawan/v3/api.swagger.json b/api/ttn/lorawan/v3/api.swagger.json index 22f5eef929..db903f784a 100644 --- a/api/ttn/lorawan/v3/api.swagger.json +++ b/api/ttn/lorawan/v3/api.swagger.json @@ -17244,6 +17244,18 @@ } } }, + "BandDescriptionRelayParameters": { + "type": "object", + "properties": { + "wor_channels": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/RelayParametersRelayWORChannel" + } + } + } + }, "BandDescriptionRx2Parameters": { "type": "object", "properties": { @@ -18419,6 +18431,22 @@ "default": "ENABLED", "description": " - ENABLED: No restrictions are in place.\n - WARNING: Warnings are being emitted that the provider will be deprecated in the future.\n - DISABLED: New integrations cannot be set up, and old ones do not start." }, + "RelayParametersRelayWORChannel": { + "type": "object", + "properties": { + "frequency": { + "type": "string", + "format": "uint64" + }, + "ack_frequency": { + "type": "string", + "format": "uint64" + }, + "data_rate_index": { + "$ref": "#/definitions/v3DataRateIndex" + } + } + }, "TxAcknowledgmentResult": { "type": "string", "enum": [ @@ -20356,6 +20384,9 @@ }, "boot_dwell_time": { "$ref": "#/definitions/BandDescriptionDwellTime" + }, + "relay": { + "$ref": "#/definitions/BandDescriptionRelayParameters" } } }, diff --git a/api/ttn/lorawan/v3/configuration_services.proto b/api/ttn/lorawan/v3/configuration_services.proto index e1911b8569..13afebd7c1 100644 --- a/api/ttn/lorawan/v3/configuration_services.proto +++ b/api/ttn/lorawan/v3/configuration_services.proto @@ -156,6 +156,17 @@ message BandDescription { } DwellTime boot_dwell_time = 31; + + message RelayParameters { + message RelayWORChannel { + uint64 frequency = 1; + uint64 ack_frequency = 2; + DataRateIndex data_rate_index = 3; + } + repeated RelayWORChannel wor_channels = 1; + } + + RelayParameters relay = 33; } message ListBandsResponse { diff --git a/pkg/band/rpc.go b/pkg/band/rpc.go index 0aa4a07eb1..b8ef75c397 100644 --- a/pkg/band/rpc.go +++ b/pkg/band/rpc.go @@ -147,6 +147,7 @@ func (b Band) BandDescription() *ttnpb.BandDescription { Frequency: b.DefaultRx2Parameters.Frequency, }, BootDwellTime: &ttnpb.BandDescription_DwellTime{}, + Relay: &ttnpb.BandDescription_RelayParameters{}, } for _, channel := range b.UplinkChannels { @@ -194,5 +195,15 @@ func (b Band) BandDescription() *ttnpb.BandDescription { } } + for _, ch := range b.Relay.WORChannels { + bandDescription.Relay.WorChannels = append( + bandDescription.Relay.WorChannels, &ttnpb.BandDescription_RelayParameters_RelayWORChannel{ + Frequency: ch.Frequency, + AckFrequency: ch.ACKFrequency, + DataRateIndex: ch.DataRateIndex, + }, + ) + } + return bandDescription } diff --git a/pkg/band/rpc_test.go b/pkg/band/rpc_test.go index e69e466e8f..cc72aaff20 100644 --- a/pkg/band/rpc_test.go +++ b/pkg/band/rpc_test.go @@ -15,7 +15,6 @@ package band_test import ( - "context" "sort" "testing" "time" @@ -24,6 +23,7 @@ import ( . "go.thethings.network/lorawan-stack/v3/pkg/band" "go.thethings.network/lorawan-stack/v3/pkg/errors" "go.thethings.network/lorawan-stack/v3/pkg/ttnpb" + "go.thethings.network/lorawan-stack/v3/pkg/util/test" "go.thethings.network/lorawan-stack/v3/pkg/util/test/assertions/should" "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/wrapperspb" @@ -31,8 +31,7 @@ import ( func TestGetPhyVersions(t *testing.T) { t.Parallel() - a := assertions.New(t) - ctx := context.Background() + a, ctx := test.New(t) for _, tc := range []struct { Name string @@ -408,7 +407,7 @@ func TestGetPhyVersions(t *testing.T) { } } -func TestBand_convertToBandDescription(t *testing.T) { +func TestBandConvertToBandDescription(t *testing.T) { t.Parallel() a := assertions.New(t) @@ -481,6 +480,21 @@ func TestBand_convertToBandDescription(t *testing.T) { Downlinks: BoolPtr(true), }, + Relay: RelayParameters{ + WORChannels: []RelayWORChannel{ + { + Frequency: 1, + ACKFrequency: 2, + DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1, + }, + { + Frequency: 3, + ACKFrequency: 4, + DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_2, + }, + }, + }, + SharedParameters: SharedParameters{ ReceiveDelay1: 1 * time.Second, ReceiveDelay2: 2 * time.Second, @@ -562,6 +576,21 @@ func TestBand_convertToBandDescription(t *testing.T) { Uplinks: &wrapperspb.BoolValue{Value: true}, Downlinks: &wrapperspb.BoolValue{Value: true}, }, + + Relay: &ttnpb.BandDescription_RelayParameters{ + WorChannels: []*ttnpb.BandDescription_RelayParameters_RelayWORChannel{ + { + Frequency: 1, + AckFrequency: 2, + DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1, + }, + { + Frequency: 3, + AckFrequency: 4, + DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_2, + }, + }, + }, }, }, { @@ -622,6 +651,21 @@ func TestBand_convertToBandDescription(t *testing.T) { BootDwellTime: DwellTime{}, + Relay: RelayParameters{ + WORChannels: []RelayWORChannel{ + { + Frequency: 1, + ACKFrequency: 2, + DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1, + }, + { + Frequency: 3, + ACKFrequency: 4, + DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_2, + }, + }, + }, + SharedParameters: SharedParameters{ ReceiveDelay1: 1 * time.Second, ReceiveDelay2: 2 * time.Second, @@ -700,6 +744,21 @@ func TestBand_convertToBandDescription(t *testing.T) { }, BootDwellTime: &ttnpb.BandDescription_DwellTime{}, + + Relay: &ttnpb.BandDescription_RelayParameters{ + WorChannels: []*ttnpb.BandDescription_RelayParameters_RelayWORChannel{ + { + Frequency: 1, + AckFrequency: 2, + DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_1, + }, + { + Frequency: 3, + AckFrequency: 4, + DataRateIndex: ttnpb.DataRateIndex_DATA_RATE_2, + }, + }, + }, }, }, } { @@ -739,8 +798,7 @@ func convertBands(input map[string]map[ttnpb.PHYVersion]Band) map[string]*ttnpb. func TestListBands(t *testing.T) { t.Parallel() - a := assertions.New(t) - ctx := context.Background() + a, ctx := test.New(t) for _, tc := range []struct { Name string diff --git a/pkg/ttnpb/configuration_services.pb.go b/pkg/ttnpb/configuration_services.pb.go index 57238e657b..8efa76b9df 100644 --- a/pkg/ttnpb/configuration_services.pb.go +++ b/pkg/ttnpb/configuration_services.pb.go @@ -394,6 +394,7 @@ type BandDescription struct { DefaultMaxEirp float32 `protobuf:"fixed32,25,opt,name=default_max_eirp,json=defaultMaxEirp,proto3" json:"default_max_eirp,omitempty"` DefaultRx2Parameters *BandDescription_Rx2Parameters `protobuf:"bytes,30,opt,name=default_rx2_parameters,json=defaultRx2Parameters,proto3" json:"default_rx2_parameters,omitempty"` BootDwellTime *BandDescription_DwellTime `protobuf:"bytes,31,opt,name=boot_dwell_time,json=bootDwellTime,proto3" json:"boot_dwell_time,omitempty"` + Relay *BandDescription_RelayParameters `protobuf:"bytes,33,opt,name=relay,proto3" json:"relay,omitempty"` } func (x *BandDescription) Reset() { @@ -617,6 +618,13 @@ func (x *BandDescription) GetBootDwellTime() *BandDescription_DwellTime { return nil } +func (x *BandDescription) GetRelay() *BandDescription_RelayParameters { + if x != nil { + return x.Relay + } + return nil +} + type ListBandsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1073,6 +1081,116 @@ func (x *BandDescription_DwellTime) GetDownlinks() *wrapperspb.BoolValue { return nil } +type BandDescription_RelayParameters struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + WorChannels []*BandDescription_RelayParameters_RelayWORChannel `protobuf:"bytes,1,rep,name=wor_channels,json=worChannels,proto3" json:"wor_channels,omitempty"` +} + +func (x *BandDescription_RelayParameters) Reset() { + *x = BandDescription_RelayParameters{} + if protoimpl.UnsafeEnabled { + mi := &file_ttn_lorawan_v3_configuration_services_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BandDescription_RelayParameters) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BandDescription_RelayParameters) ProtoMessage() {} + +func (x *BandDescription_RelayParameters) ProtoReflect() protoreflect.Message { + mi := &file_ttn_lorawan_v3_configuration_services_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BandDescription_RelayParameters.ProtoReflect.Descriptor instead. +func (*BandDescription_RelayParameters) Descriptor() ([]byte, []int) { + return file_ttn_lorawan_v3_configuration_services_proto_rawDescGZIP(), []int{6, 7} +} + +func (x *BandDescription_RelayParameters) GetWorChannels() []*BandDescription_RelayParameters_RelayWORChannel { + if x != nil { + return x.WorChannels + } + return nil +} + +type BandDescription_RelayParameters_RelayWORChannel struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Frequency uint64 `protobuf:"varint,1,opt,name=frequency,proto3" json:"frequency,omitempty"` + AckFrequency uint64 `protobuf:"varint,2,opt,name=ack_frequency,json=ackFrequency,proto3" json:"ack_frequency,omitempty"` + DataRateIndex DataRateIndex `protobuf:"varint,3,opt,name=data_rate_index,json=dataRateIndex,proto3,enum=ttn.lorawan.v3.DataRateIndex" json:"data_rate_index,omitempty"` +} + +func (x *BandDescription_RelayParameters_RelayWORChannel) Reset() { + *x = BandDescription_RelayParameters_RelayWORChannel{} + if protoimpl.UnsafeEnabled { + mi := &file_ttn_lorawan_v3_configuration_services_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BandDescription_RelayParameters_RelayWORChannel) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BandDescription_RelayParameters_RelayWORChannel) ProtoMessage() {} + +func (x *BandDescription_RelayParameters_RelayWORChannel) ProtoReflect() protoreflect.Message { + mi := &file_ttn_lorawan_v3_configuration_services_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BandDescription_RelayParameters_RelayWORChannel.ProtoReflect.Descriptor instead. +func (*BandDescription_RelayParameters_RelayWORChannel) Descriptor() ([]byte, []int) { + return file_ttn_lorawan_v3_configuration_services_proto_rawDescGZIP(), []int{6, 7, 0} +} + +func (x *BandDescription_RelayParameters_RelayWORChannel) GetFrequency() uint64 { + if x != nil { + return x.Frequency + } + return 0 +} + +func (x *BandDescription_RelayParameters_RelayWORChannel) GetAckFrequency() uint64 { + if x != nil { + return x.AckFrequency + } + return 0 +} + +func (x *BandDescription_RelayParameters_RelayWORChannel) GetDataRateIndex() DataRateIndex { + if x != nil { + return x.DataRateIndex + } + return DataRateIndex_DATA_RATE_0 +} + type ListBandsResponse_VersionedBandDescription struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1084,7 +1202,7 @@ type ListBandsResponse_VersionedBandDescription struct { func (x *ListBandsResponse_VersionedBandDescription) Reset() { *x = ListBandsResponse_VersionedBandDescription{} if protoimpl.UnsafeEnabled { - mi := &file_ttn_lorawan_v3_configuration_services_proto_msgTypes[16] + mi := &file_ttn_lorawan_v3_configuration_services_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1097,7 +1215,7 @@ func (x *ListBandsResponse_VersionedBandDescription) String() string { func (*ListBandsResponse_VersionedBandDescription) ProtoMessage() {} func (x *ListBandsResponse_VersionedBandDescription) ProtoReflect() protoreflect.Message { - mi := &file_ttn_lorawan_v3_configuration_services_proto_msgTypes[16] + mi := &file_ttn_lorawan_v3_configuration_services_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1183,7 +1301,7 @@ var file_ttn_lorawan_v3_configuration_services_proto_rawDesc = []byte{ 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x48, 0x59, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x70, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x08, 0xf2, - 0xaa, 0x19, 0x04, 0x08, 0x00, 0x10, 0x01, 0x22, 0xea, 0x14, 0x0a, 0x0f, 0x42, 0x61, 0x6e, 0x64, + 0xaa, 0x19, 0x04, 0x08, 0x00, 0x10, 0x01, 0x22, 0xc7, 0x17, 0x0a, 0x0f, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3e, 0x0a, 0x06, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, @@ -1291,128 +1409,150 @@ var file_ttn_lorawan_v3_configuration_services_proto_rawDesc = []byte{ 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x62, 0x6f, 0x6f, 0x74, 0x44, - 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x1a, 0x9e, 0x01, 0x0a, 0x06, 0x42, 0x65, 0x61, - 0x63, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, - 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, - 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, - 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x64, 0x61, 0x74, - 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, - 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x66, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x04, - 0x52, 0x0b, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x4a, 0x04, 0x08, - 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x1a, 0xad, 0x01, 0x0a, 0x07, 0x43, 0x68, - 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x6e, 0x63, 0x79, 0x12, 0x41, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, - 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, - 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, - 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0b, 0x6d, 0x69, 0x6e, 0x44, 0x61, - 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x12, 0x41, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x61, - 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, - 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, - 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0b, 0x6d, 0x61, - 0x78, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x1a, 0x97, 0x01, 0x0a, 0x11, 0x53, 0x75, - 0x62, 0x42, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, - 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, - 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x75, 0x74, - 0x79, 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x64, - 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, - 0x65, 0x69, 0x72, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x45, - 0x69, 0x72, 0x70, 0x1a, 0x42, 0x0a, 0x0c, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, - 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x72, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, - 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52, 0x04, 0x72, 0x61, 0x74, - 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x1a, 0x6a, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x52, - 0x61, 0x74, 0x65, 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, 0x42, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x74, 0x6e, - 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, - 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x61, 0x6e, 0x64, - 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x1a, 0x74, 0x0a, 0x0d, 0x52, 0x78, 0x32, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x73, 0x12, 0x45, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, - 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, - 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, - 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x64, 0x61, - 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x66, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, - 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x1a, 0x7b, 0x0a, 0x09, 0x44, 0x77, 0x65, - 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x07, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x38, 0x0a, 0x09, - 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x64, 0x6f, 0x77, - 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x1a, - 0x10, 0x1b, 0x4a, 0x04, 0x08, 0x1b, 0x10, 0x1c, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, - 0x08, 0x1d, 0x10, 0x1e, 0x22, 0xba, 0x03, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, - 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x0c, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x33, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, - 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x1a, 0xce, 0x01, 0x0a, 0x18, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, - 0x64, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x58, 0x0a, 0x04, 0x62, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, - 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x6e, 0x64, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x62, 0x61, 0x6e, 0x64, 0x1a, 0x58, 0x0a, 0x09, 0x42, 0x61, - 0x6e, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, - 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x7b, 0x0a, 0x11, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x50, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x74, 0x6e, - 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, + 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x05, 0x72, 0x65, 0x6c, 0x61, + 0x79, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, + 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x05, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x1a, + 0x9e, 0x01, 0x0a, 0x06, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x0f, 0x64, 0x61, + 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, + 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x61, 0x74, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x61, + 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x04, 0x52, 0x0b, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x63, 0x69, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, + 0x1a, 0xad, 0x01, 0x0a, 0x07, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, + 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x41, 0x0a, 0x0d, 0x6d, 0x69, + 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, + 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x52, 0x0b, 0x6d, 0x69, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x12, 0x41, 0x0a, + 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, + 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, + 0x1a, 0x97, 0x01, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x42, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f, 0x66, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, + 0x69, 0x6e, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x6d, + 0x61, 0x78, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, + 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x75, 0x74, 0x79, 0x5f, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x02, 0x52, 0x09, 0x64, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x12, + 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x69, 0x72, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x02, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x45, 0x69, 0x72, 0x70, 0x1a, 0x42, 0x0a, 0x0c, 0x42, 0x61, + 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x72, 0x61, + 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, + 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, + 0x74, 0x65, 0x52, 0x04, 0x72, 0x61, 0x74, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x1a, 0x6a, + 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 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, 0x42, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, + 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x74, 0x0a, 0x0d, 0x52, 0x78, + 0x32, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x45, 0x0a, 0x0f, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, + 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, + 0x1a, 0x7b, 0x0a, 0x09, 0x44, 0x77, 0x65, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x34, 0x0a, + 0x07, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x75, 0x70, 0x6c, 0x69, + 0x6e, 0x6b, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x1a, 0x93, 0x02, + 0x0a, 0x0f, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x73, 0x12, 0x62, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, + 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x57, 0x4f, + 0x52, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x43, 0x68, 0x61, + 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x1a, 0x9b, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x57, + 0x4f, 0x52, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x63, 0x6b, 0x5f, 0x66, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, + 0x61, 0x63, 0x6b, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x45, 0x0a, 0x0f, + 0x64, 0x61, 0x74, 0x61, 0x5f, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, + 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x52, 0x61, 0x74, 0x65, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x1a, 0x10, 0x1b, 0x4a, + 0x04, 0x08, 0x1b, 0x10, 0x1c, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x1d, 0x10, + 0x1e, 0x22, 0xba, 0x03, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, + 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x1a, 0xce, 0x01, 0x0a, 0x18, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x61, + 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x58, 0x0a, + 0x04, 0x62, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x74, 0x74, + 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x04, 0x62, 0x61, 0x6e, 0x64, 0x1a, 0x58, 0x0a, 0x09, 0x42, 0x61, 0x6e, 0x64, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, + 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x32, 0xef, 0x03, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x93, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x74, 0x74, 0x6e, - 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, - 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x6e, 0x63, 0x79, 0x2d, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x12, 0x84, 0x01, 0x0a, 0x0e, 0x47, 0x65, - 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x2e, 0x74, - 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, - 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, - 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2f, 0x70, 0x68, 0x79, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0xc0, 0x01, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x20, - 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x21, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, - 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x68, 0x5a, 0x20, 0x12, 0x1e, 0x2f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, - 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x7d, 0x5a, 0x2e, 0x12, - 0x2c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, - 0x62, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x7b, 0x70, 0x68, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x14, 0x2f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, - 0x6e, 0x64, 0x73, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, - 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, - 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, - 0x2f, 0x74, 0x74, 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x01, 0x1a, 0x7b, 0x0a, 0x11, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x50, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, + 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, + 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xef, + 0x03, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x93, 0x01, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, + 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, + 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, + 0x79, 0x50, 0x6c, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, + 0x2d, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x12, 0x84, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x68, + 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x2e, 0x74, 0x74, 0x6e, 0x2e, + 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68, + 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, + 0x33, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x68, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, + 0x12, 0x1b, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x70, 0x68, 0x79, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xc0, 0x01, + 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x20, 0x2e, 0x74, 0x74, + 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, + 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x68, 0x5a, 0x20, 0x12, 0x1e, 0x2f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x6e, 0x64, 0x73, + 0x2f, 0x7b, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x7d, 0x5a, 0x2e, 0x12, 0x2c, 0x2f, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x6e, + 0x64, 0x73, 0x2f, 0x7b, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x70, 0x68, + 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x14, 0x2f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x6e, 0x64, 0x73, + 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, + 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, + 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, + 0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1427,79 +1567,84 @@ func file_ttn_lorawan_v3_configuration_services_proto_rawDescGZIP() []byte { return file_ttn_lorawan_v3_configuration_services_proto_rawDescData } -var file_ttn_lorawan_v3_configuration_services_proto_msgTypes = make([]protoimpl.MessageInfo, 19) +var file_ttn_lorawan_v3_configuration_services_proto_msgTypes = make([]protoimpl.MessageInfo, 21) var file_ttn_lorawan_v3_configuration_services_proto_goTypes = []interface{}{ - (*ListFrequencyPlansRequest)(nil), // 0: ttn.lorawan.v3.ListFrequencyPlansRequest - (*FrequencyPlanDescription)(nil), // 1: ttn.lorawan.v3.FrequencyPlanDescription - (*ListFrequencyPlansResponse)(nil), // 2: ttn.lorawan.v3.ListFrequencyPlansResponse - (*GetPhyVersionsRequest)(nil), // 3: ttn.lorawan.v3.GetPhyVersionsRequest - (*GetPhyVersionsResponse)(nil), // 4: ttn.lorawan.v3.GetPhyVersionsResponse - (*ListBandsRequest)(nil), // 5: ttn.lorawan.v3.ListBandsRequest - (*BandDescription)(nil), // 6: ttn.lorawan.v3.BandDescription - (*ListBandsResponse)(nil), // 7: ttn.lorawan.v3.ListBandsResponse - (*GetPhyVersionsResponse_VersionInfo)(nil), // 8: ttn.lorawan.v3.GetPhyVersionsResponse.VersionInfo - (*BandDescription_Beacon)(nil), // 9: ttn.lorawan.v3.BandDescription.Beacon - (*BandDescription_Channel)(nil), // 10: ttn.lorawan.v3.BandDescription.Channel - (*BandDescription_SubBandParameters)(nil), // 11: ttn.lorawan.v3.BandDescription.SubBandParameters - (*BandDescription_BandDataRate)(nil), // 12: ttn.lorawan.v3.BandDescription.BandDataRate - nil, // 13: ttn.lorawan.v3.BandDescription.DataRatesEntry - (*BandDescription_Rx2Parameters)(nil), // 14: ttn.lorawan.v3.BandDescription.Rx2Parameters - (*BandDescription_DwellTime)(nil), // 15: ttn.lorawan.v3.BandDescription.DwellTime - (*ListBandsResponse_VersionedBandDescription)(nil), // 16: ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription - nil, // 17: ttn.lorawan.v3.ListBandsResponse.DescriptionsEntry - nil, // 18: ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.BandEntry - (PHYVersion)(0), // 19: ttn.lorawan.v3.PHYVersion - (CFListType)(0), // 20: ttn.lorawan.v3.CFListType - (*durationpb.Duration)(nil), // 21: google.protobuf.Duration - (ADRAckLimitExponent)(0), // 22: ttn.lorawan.v3.ADRAckLimitExponent - (DataRateIndex)(0), // 23: ttn.lorawan.v3.DataRateIndex - (*DataRate)(nil), // 24: ttn.lorawan.v3.DataRate - (*wrapperspb.BoolValue)(nil), // 25: google.protobuf.BoolValue + (*ListFrequencyPlansRequest)(nil), // 0: ttn.lorawan.v3.ListFrequencyPlansRequest + (*FrequencyPlanDescription)(nil), // 1: ttn.lorawan.v3.FrequencyPlanDescription + (*ListFrequencyPlansResponse)(nil), // 2: ttn.lorawan.v3.ListFrequencyPlansResponse + (*GetPhyVersionsRequest)(nil), // 3: ttn.lorawan.v3.GetPhyVersionsRequest + (*GetPhyVersionsResponse)(nil), // 4: ttn.lorawan.v3.GetPhyVersionsResponse + (*ListBandsRequest)(nil), // 5: ttn.lorawan.v3.ListBandsRequest + (*BandDescription)(nil), // 6: ttn.lorawan.v3.BandDescription + (*ListBandsResponse)(nil), // 7: ttn.lorawan.v3.ListBandsResponse + (*GetPhyVersionsResponse_VersionInfo)(nil), // 8: ttn.lorawan.v3.GetPhyVersionsResponse.VersionInfo + (*BandDescription_Beacon)(nil), // 9: ttn.lorawan.v3.BandDescription.Beacon + (*BandDescription_Channel)(nil), // 10: ttn.lorawan.v3.BandDescription.Channel + (*BandDescription_SubBandParameters)(nil), // 11: ttn.lorawan.v3.BandDescription.SubBandParameters + (*BandDescription_BandDataRate)(nil), // 12: ttn.lorawan.v3.BandDescription.BandDataRate + nil, // 13: ttn.lorawan.v3.BandDescription.DataRatesEntry + (*BandDescription_Rx2Parameters)(nil), // 14: ttn.lorawan.v3.BandDescription.Rx2Parameters + (*BandDescription_DwellTime)(nil), // 15: ttn.lorawan.v3.BandDescription.DwellTime + (*BandDescription_RelayParameters)(nil), // 16: ttn.lorawan.v3.BandDescription.RelayParameters + (*BandDescription_RelayParameters_RelayWORChannel)(nil), // 17: ttn.lorawan.v3.BandDescription.RelayParameters.RelayWORChannel + (*ListBandsResponse_VersionedBandDescription)(nil), // 18: ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription + nil, // 19: ttn.lorawan.v3.ListBandsResponse.DescriptionsEntry + nil, // 20: ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.BandEntry + (PHYVersion)(0), // 21: ttn.lorawan.v3.PHYVersion + (CFListType)(0), // 22: ttn.lorawan.v3.CFListType + (*durationpb.Duration)(nil), // 23: google.protobuf.Duration + (ADRAckLimitExponent)(0), // 24: ttn.lorawan.v3.ADRAckLimitExponent + (DataRateIndex)(0), // 25: ttn.lorawan.v3.DataRateIndex + (*DataRate)(nil), // 26: ttn.lorawan.v3.DataRate + (*wrapperspb.BoolValue)(nil), // 27: google.protobuf.BoolValue } var file_ttn_lorawan_v3_configuration_services_proto_depIdxs = []int32{ 1, // 0: ttn.lorawan.v3.ListFrequencyPlansResponse.frequency_plans:type_name -> ttn.lorawan.v3.FrequencyPlanDescription 8, // 1: ttn.lorawan.v3.GetPhyVersionsResponse.version_info:type_name -> ttn.lorawan.v3.GetPhyVersionsResponse.VersionInfo - 19, // 2: ttn.lorawan.v3.ListBandsRequest.phy_version:type_name -> ttn.lorawan.v3.PHYVersion + 21, // 2: ttn.lorawan.v3.ListBandsRequest.phy_version:type_name -> ttn.lorawan.v3.PHYVersion 9, // 3: ttn.lorawan.v3.BandDescription.beacon:type_name -> ttn.lorawan.v3.BandDescription.Beacon 10, // 4: ttn.lorawan.v3.BandDescription.uplink_channels:type_name -> ttn.lorawan.v3.BandDescription.Channel 10, // 5: ttn.lorawan.v3.BandDescription.downlink_channels:type_name -> ttn.lorawan.v3.BandDescription.Channel 11, // 6: ttn.lorawan.v3.BandDescription.sub_bands:type_name -> ttn.lorawan.v3.BandDescription.SubBandParameters 13, // 7: ttn.lorawan.v3.BandDescription.data_rates:type_name -> ttn.lorawan.v3.BandDescription.DataRatesEntry - 20, // 8: ttn.lorawan.v3.BandDescription.cf_list_type:type_name -> ttn.lorawan.v3.CFListType - 21, // 9: ttn.lorawan.v3.BandDescription.receive_delay_1:type_name -> google.protobuf.Duration - 21, // 10: ttn.lorawan.v3.BandDescription.receive_delay_2:type_name -> google.protobuf.Duration - 21, // 11: ttn.lorawan.v3.BandDescription.join_accept_delay_1:type_name -> google.protobuf.Duration - 21, // 12: ttn.lorawan.v3.BandDescription.join_accept_delay_2:type_name -> google.protobuf.Duration - 22, // 13: ttn.lorawan.v3.BandDescription.adr_ack_limit:type_name -> ttn.lorawan.v3.ADRAckLimitExponent - 21, // 14: ttn.lorawan.v3.BandDescription.min_retransmit_timeout:type_name -> google.protobuf.Duration - 21, // 15: ttn.lorawan.v3.BandDescription.max_retransmit_timeout:type_name -> google.protobuf.Duration - 23, // 16: ttn.lorawan.v3.BandDescription.max_adr_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex + 22, // 8: ttn.lorawan.v3.BandDescription.cf_list_type:type_name -> ttn.lorawan.v3.CFListType + 23, // 9: ttn.lorawan.v3.BandDescription.receive_delay_1:type_name -> google.protobuf.Duration + 23, // 10: ttn.lorawan.v3.BandDescription.receive_delay_2:type_name -> google.protobuf.Duration + 23, // 11: ttn.lorawan.v3.BandDescription.join_accept_delay_1:type_name -> google.protobuf.Duration + 23, // 12: ttn.lorawan.v3.BandDescription.join_accept_delay_2:type_name -> google.protobuf.Duration + 24, // 13: ttn.lorawan.v3.BandDescription.adr_ack_limit:type_name -> ttn.lorawan.v3.ADRAckLimitExponent + 23, // 14: ttn.lorawan.v3.BandDescription.min_retransmit_timeout:type_name -> google.protobuf.Duration + 23, // 15: ttn.lorawan.v3.BandDescription.max_retransmit_timeout:type_name -> google.protobuf.Duration + 25, // 16: ttn.lorawan.v3.BandDescription.max_adr_data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex 14, // 17: ttn.lorawan.v3.BandDescription.default_rx2_parameters:type_name -> ttn.lorawan.v3.BandDescription.Rx2Parameters 15, // 18: ttn.lorawan.v3.BandDescription.boot_dwell_time:type_name -> ttn.lorawan.v3.BandDescription.DwellTime - 17, // 19: ttn.lorawan.v3.ListBandsResponse.descriptions:type_name -> ttn.lorawan.v3.ListBandsResponse.DescriptionsEntry - 19, // 20: ttn.lorawan.v3.GetPhyVersionsResponse.VersionInfo.phy_versions:type_name -> ttn.lorawan.v3.PHYVersion - 23, // 21: ttn.lorawan.v3.BandDescription.Beacon.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex - 23, // 22: ttn.lorawan.v3.BandDescription.Channel.min_data_rate:type_name -> ttn.lorawan.v3.DataRateIndex - 23, // 23: ttn.lorawan.v3.BandDescription.Channel.max_data_rate:type_name -> ttn.lorawan.v3.DataRateIndex - 24, // 24: ttn.lorawan.v3.BandDescription.BandDataRate.rate:type_name -> ttn.lorawan.v3.DataRate - 12, // 25: ttn.lorawan.v3.BandDescription.DataRatesEntry.value:type_name -> ttn.lorawan.v3.BandDescription.BandDataRate - 23, // 26: ttn.lorawan.v3.BandDescription.Rx2Parameters.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex - 25, // 27: ttn.lorawan.v3.BandDescription.DwellTime.uplinks:type_name -> google.protobuf.BoolValue - 25, // 28: ttn.lorawan.v3.BandDescription.DwellTime.downlinks:type_name -> google.protobuf.BoolValue - 18, // 29: ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.band:type_name -> ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.BandEntry - 16, // 30: ttn.lorawan.v3.ListBandsResponse.DescriptionsEntry.value:type_name -> ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription - 6, // 31: ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.BandEntry.value:type_name -> ttn.lorawan.v3.BandDescription - 0, // 32: ttn.lorawan.v3.Configuration.ListFrequencyPlans:input_type -> ttn.lorawan.v3.ListFrequencyPlansRequest - 3, // 33: ttn.lorawan.v3.Configuration.GetPhyVersions:input_type -> ttn.lorawan.v3.GetPhyVersionsRequest - 5, // 34: ttn.lorawan.v3.Configuration.ListBands:input_type -> ttn.lorawan.v3.ListBandsRequest - 2, // 35: ttn.lorawan.v3.Configuration.ListFrequencyPlans:output_type -> ttn.lorawan.v3.ListFrequencyPlansResponse - 4, // 36: ttn.lorawan.v3.Configuration.GetPhyVersions:output_type -> ttn.lorawan.v3.GetPhyVersionsResponse - 7, // 37: ttn.lorawan.v3.Configuration.ListBands:output_type -> ttn.lorawan.v3.ListBandsResponse - 35, // [35:38] is the sub-list for method output_type - 32, // [32:35] is the sub-list for method input_type - 32, // [32:32] is the sub-list for extension type_name - 32, // [32:32] is the sub-list for extension extendee - 0, // [0:32] is the sub-list for field type_name + 16, // 19: ttn.lorawan.v3.BandDescription.relay:type_name -> ttn.lorawan.v3.BandDescription.RelayParameters + 19, // 20: ttn.lorawan.v3.ListBandsResponse.descriptions:type_name -> ttn.lorawan.v3.ListBandsResponse.DescriptionsEntry + 21, // 21: ttn.lorawan.v3.GetPhyVersionsResponse.VersionInfo.phy_versions:type_name -> ttn.lorawan.v3.PHYVersion + 25, // 22: ttn.lorawan.v3.BandDescription.Beacon.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex + 25, // 23: ttn.lorawan.v3.BandDescription.Channel.min_data_rate:type_name -> ttn.lorawan.v3.DataRateIndex + 25, // 24: ttn.lorawan.v3.BandDescription.Channel.max_data_rate:type_name -> ttn.lorawan.v3.DataRateIndex + 26, // 25: ttn.lorawan.v3.BandDescription.BandDataRate.rate:type_name -> ttn.lorawan.v3.DataRate + 12, // 26: ttn.lorawan.v3.BandDescription.DataRatesEntry.value:type_name -> ttn.lorawan.v3.BandDescription.BandDataRate + 25, // 27: ttn.lorawan.v3.BandDescription.Rx2Parameters.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex + 27, // 28: ttn.lorawan.v3.BandDescription.DwellTime.uplinks:type_name -> google.protobuf.BoolValue + 27, // 29: ttn.lorawan.v3.BandDescription.DwellTime.downlinks:type_name -> google.protobuf.BoolValue + 17, // 30: ttn.lorawan.v3.BandDescription.RelayParameters.wor_channels:type_name -> ttn.lorawan.v3.BandDescription.RelayParameters.RelayWORChannel + 25, // 31: ttn.lorawan.v3.BandDescription.RelayParameters.RelayWORChannel.data_rate_index:type_name -> ttn.lorawan.v3.DataRateIndex + 20, // 32: ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.band:type_name -> ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.BandEntry + 18, // 33: ttn.lorawan.v3.ListBandsResponse.DescriptionsEntry.value:type_name -> ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription + 6, // 34: ttn.lorawan.v3.ListBandsResponse.VersionedBandDescription.BandEntry.value:type_name -> ttn.lorawan.v3.BandDescription + 0, // 35: ttn.lorawan.v3.Configuration.ListFrequencyPlans:input_type -> ttn.lorawan.v3.ListFrequencyPlansRequest + 3, // 36: ttn.lorawan.v3.Configuration.GetPhyVersions:input_type -> ttn.lorawan.v3.GetPhyVersionsRequest + 5, // 37: ttn.lorawan.v3.Configuration.ListBands:input_type -> ttn.lorawan.v3.ListBandsRequest + 2, // 38: ttn.lorawan.v3.Configuration.ListFrequencyPlans:output_type -> ttn.lorawan.v3.ListFrequencyPlansResponse + 4, // 39: ttn.lorawan.v3.Configuration.GetPhyVersions:output_type -> ttn.lorawan.v3.GetPhyVersionsResponse + 7, // 40: ttn.lorawan.v3.Configuration.ListBands:output_type -> ttn.lorawan.v3.ListBandsResponse + 38, // [38:41] is the sub-list for method output_type + 35, // [35:38] is the sub-list for method input_type + 35, // [35:35] is the sub-list for extension type_name + 35, // [35:35] is the sub-list for extension extendee + 0, // [0:35] is the sub-list for field type_name } func init() { file_ttn_lorawan_v3_configuration_services_proto_init() } @@ -1690,6 +1835,30 @@ func file_ttn_lorawan_v3_configuration_services_proto_init() { } } file_ttn_lorawan_v3_configuration_services_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BandDescription_RelayParameters); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ttn_lorawan_v3_configuration_services_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BandDescription_RelayParameters_RelayWORChannel); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ttn_lorawan_v3_configuration_services_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListBandsResponse_VersionedBandDescription); i { case 0: return &v.state @@ -1708,7 +1877,7 @@ func file_ttn_lorawan_v3_configuration_services_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_ttn_lorawan_v3_configuration_services_proto_rawDesc, NumEnums: 0, - NumMessages: 19, + NumMessages: 21, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/ttnpb/configuration_services.pb.paths.fm.go b/pkg/ttnpb/configuration_services.pb.paths.fm.go index 527ab1b907..95895132bb 100644 --- a/pkg/ttnpb/configuration_services.pb.paths.fm.go +++ b/pkg/ttnpb/configuration_services.pb.paths.fm.go @@ -82,6 +82,8 @@ var BandDescriptionFieldPathsNested = []string{ "ping_slot_frequencies", "receive_delay_1", "receive_delay_2", + "relay", + "relay.wor_channels", "sub_bands", "supports_dynamic_adr", "tx_offset", @@ -112,6 +114,7 @@ var BandDescriptionFieldPathsTopLevel = []string{ "ping_slot_frequencies", "receive_delay_1", "receive_delay_2", + "relay", "sub_bands", "supports_dynamic_adr", "tx_offset", @@ -205,6 +208,24 @@ var BandDescription_DwellTimeFieldPathsTopLevel = []string{ "downlinks", "uplinks", } +var BandDescription_RelayParametersFieldPathsNested = []string{ + "wor_channels", +} + +var BandDescription_RelayParametersFieldPathsTopLevel = []string{ + "wor_channels", +} +var BandDescription_RelayParameters_RelayWORChannelFieldPathsNested = []string{ + "ack_frequency", + "data_rate_index", + "frequency", +} + +var BandDescription_RelayParameters_RelayWORChannelFieldPathsTopLevel = []string{ + "ack_frequency", + "data_rate_index", + "frequency", +} var ListBandsResponse_VersionedBandDescriptionFieldPathsNested = []string{ "band", } diff --git a/pkg/ttnpb/configuration_services.pb.setters.fm.go b/pkg/ttnpb/configuration_services.pb.setters.fm.go index 5d680cffd4..2c93fe5910 100644 --- a/pkg/ttnpb/configuration_services.pb.setters.fm.go +++ b/pkg/ttnpb/configuration_services.pb.setters.fm.go @@ -470,6 +470,31 @@ func (dst *BandDescription) SetFields(src *BandDescription, paths ...string) err dst.BootDwellTime = nil } } + case "relay": + if len(subs) > 0 { + var newDst, newSrc *BandDescription_RelayParameters + if (src == nil || src.Relay == nil) && dst.Relay == nil { + continue + } + if src != nil { + newSrc = src.Relay + } + if dst.Relay != nil { + newDst = dst.Relay + } else { + newDst = &BandDescription_RelayParameters{} + dst.Relay = newDst + } + if err := newDst.SetFields(newSrc, subs...); err != nil { + return err + } + } else { + if src != nil { + dst.Relay = src.Relay + } else { + dst.Relay = nil + } + } default: return fmt.Errorf("invalid field: '%s'", name) @@ -752,6 +777,66 @@ func (dst *BandDescription_DwellTime) SetFields(src *BandDescription_DwellTime, return nil } +func (dst *BandDescription_RelayParameters) SetFields(src *BandDescription_RelayParameters, paths ...string) error { + for name, subs := range _processPaths(paths) { + switch name { + case "wor_channels": + if len(subs) > 0 { + return fmt.Errorf("'wor_channels' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.WorChannels = src.WorChannels + } else { + dst.WorChannels = nil + } + + default: + return fmt.Errorf("invalid field: '%s'", name) + } + } + return nil +} + +func (dst *BandDescription_RelayParameters_RelayWORChannel) SetFields(src *BandDescription_RelayParameters_RelayWORChannel, paths ...string) error { + for name, subs := range _processPaths(paths) { + switch name { + case "frequency": + if len(subs) > 0 { + return fmt.Errorf("'frequency' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.Frequency = src.Frequency + } else { + var zero uint64 + dst.Frequency = zero + } + case "ack_frequency": + if len(subs) > 0 { + return fmt.Errorf("'ack_frequency' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.AckFrequency = src.AckFrequency + } else { + var zero uint64 + dst.AckFrequency = zero + } + case "data_rate_index": + if len(subs) > 0 { + return fmt.Errorf("'data_rate_index' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.DataRateIndex = src.DataRateIndex + } else { + dst.DataRateIndex = 0 + } + + default: + return fmt.Errorf("invalid field: '%s'", name) + } + } + return nil +} + func (dst *ListBandsResponse_VersionedBandDescription) SetFields(src *ListBandsResponse_VersionedBandDescription, paths ...string) error { for name, subs := range _processPaths(paths) { switch name { diff --git a/pkg/ttnpb/configuration_services.pb.validate.go b/pkg/ttnpb/configuration_services.pb.validate.go index 68e6e879e0..a2e2ad41ba 100644 --- a/pkg/ttnpb/configuration_services.pb.validate.go +++ b/pkg/ttnpb/configuration_services.pb.validate.go @@ -797,6 +797,18 @@ func (m *BandDescription) ValidateFields(paths ...string) error { } } + case "relay": + + if v, ok := interface{}(m.GetRelay()).(interface{ ValidateFields(...string) error }); ok { + if err := v.ValidateFields(subs...); err != nil { + return BandDescriptionValidationError{ + field: "relay", + reason: "embedded message failed validation", + cause: err, + } + } + } + default: return BandDescriptionValidationError{ field: name, @@ -1597,6 +1609,199 @@ var _ interface { ErrorName() string } = BandDescription_DwellTimeValidationError{} +// ValidateFields checks the field values on BandDescription_RelayParameters +// with the rules defined in the proto definition for this message. If any +// rules are violated, an error is returned. +func (m *BandDescription_RelayParameters) ValidateFields(paths ...string) error { + if m == nil { + return nil + } + + if len(paths) == 0 { + paths = BandDescription_RelayParametersFieldPathsNested + } + + for name, subs := range _processPaths(append(paths[:0:0], paths...)) { + _ = subs + switch name { + case "wor_channels": + + for idx, item := range m.GetWorChannels() { + _, _ = idx, item + + if v, ok := interface{}(item).(interface{ ValidateFields(...string) error }); ok { + if err := v.ValidateFields(subs...); err != nil { + return BandDescription_RelayParametersValidationError{ + field: fmt.Sprintf("wor_channels[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + default: + return BandDescription_RelayParametersValidationError{ + field: name, + reason: "invalid field path", + } + } + } + return nil +} + +// BandDescription_RelayParametersValidationError is the validation error +// returned by BandDescription_RelayParameters.ValidateFields if the +// designated constraints aren't met. +type BandDescription_RelayParametersValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e BandDescription_RelayParametersValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e BandDescription_RelayParametersValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e BandDescription_RelayParametersValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e BandDescription_RelayParametersValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e BandDescription_RelayParametersValidationError) ErrorName() string { + return "BandDescription_RelayParametersValidationError" +} + +// Error satisfies the builtin error interface +func (e BandDescription_RelayParametersValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sBandDescription_RelayParameters.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = BandDescription_RelayParametersValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = BandDescription_RelayParametersValidationError{} + +// ValidateFields checks the field values on +// BandDescription_RelayParameters_RelayWORChannel with the rules defined in +// the proto definition for this message. If any rules are violated, an error +// is returned. +func (m *BandDescription_RelayParameters_RelayWORChannel) ValidateFields(paths ...string) error { + if m == nil { + return nil + } + + if len(paths) == 0 { + paths = BandDescription_RelayParameters_RelayWORChannelFieldPathsNested + } + + for name, subs := range _processPaths(append(paths[:0:0], paths...)) { + _ = subs + switch name { + case "frequency": + // no validation rules for Frequency + case "ack_frequency": + // no validation rules for AckFrequency + case "data_rate_index": + // no validation rules for DataRateIndex + default: + return BandDescription_RelayParameters_RelayWORChannelValidationError{ + field: name, + reason: "invalid field path", + } + } + } + return nil +} + +// BandDescription_RelayParameters_RelayWORChannelValidationError is the +// validation error returned by +// BandDescription_RelayParameters_RelayWORChannel.ValidateFields if the +// designated constraints aren't met. +type BandDescription_RelayParameters_RelayWORChannelValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e BandDescription_RelayParameters_RelayWORChannelValidationError) Field() string { + return e.field +} + +// Reason function returns reason value. +func (e BandDescription_RelayParameters_RelayWORChannelValidationError) Reason() string { + return e.reason +} + +// Cause function returns cause value. +func (e BandDescription_RelayParameters_RelayWORChannelValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e BandDescription_RelayParameters_RelayWORChannelValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e BandDescription_RelayParameters_RelayWORChannelValidationError) ErrorName() string { + return "BandDescription_RelayParameters_RelayWORChannelValidationError" +} + +// Error satisfies the builtin error interface +func (e BandDescription_RelayParameters_RelayWORChannelValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sBandDescription_RelayParameters_RelayWORChannel.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = BandDescription_RelayParameters_RelayWORChannelValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = BandDescription_RelayParameters_RelayWORChannelValidationError{} + // ValidateFields checks the field values on // ListBandsResponse_VersionedBandDescription with the rules defined in the // proto definition for this message. If any rules are violated, an error is returned. diff --git a/pkg/ttnpb/configuration_services_json.pb.go b/pkg/ttnpb/configuration_services_json.pb.go index 6f8fd3c638..22bbd70238 100644 --- a/pkg/ttnpb/configuration_services_json.pb.go +++ b/pkg/ttnpb/configuration_services_json.pb.go @@ -358,6 +358,127 @@ func (x *BandDescription_Rx2Parameters) UnmarshalJSON(b []byte) error { return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x) } +// MarshalProtoJSON marshals the BandDescription_RelayParameters_RelayWORChannel message to JSON. +func (x *BandDescription_RelayParameters_RelayWORChannel) MarshalProtoJSON(s *jsonplugin.MarshalState) { + if x == nil { + s.WriteNil() + return + } + s.WriteObjectStart() + var wroteField bool + if x.Frequency != 0 || s.HasField("frequency") { + s.WriteMoreIf(&wroteField) + s.WriteObjectField("frequency") + s.WriteUint64(x.Frequency) + } + if x.AckFrequency != 0 || s.HasField("ack_frequency") { + s.WriteMoreIf(&wroteField) + s.WriteObjectField("ack_frequency") + s.WriteUint64(x.AckFrequency) + } + if x.DataRateIndex != 0 || s.HasField("data_rate_index") { + s.WriteMoreIf(&wroteField) + s.WriteObjectField("data_rate_index") + x.DataRateIndex.MarshalProtoJSON(s) + } + s.WriteObjectEnd() +} + +// MarshalJSON marshals the BandDescription_RelayParameters_RelayWORChannel to JSON. +func (x *BandDescription_RelayParameters_RelayWORChannel) MarshalJSON() ([]byte, error) { + return jsonplugin.DefaultMarshalerConfig.Marshal(x) +} + +// UnmarshalProtoJSON unmarshals the BandDescription_RelayParameters_RelayWORChannel message from JSON. +func (x *BandDescription_RelayParameters_RelayWORChannel) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) { + if s.ReadNil() { + return + } + s.ReadObject(func(key string) { + switch key { + default: + s.ReadAny() // ignore unknown field + case "frequency": + s.AddField("frequency") + x.Frequency = s.ReadUint64() + case "ack_frequency", "ackFrequency": + s.AddField("ack_frequency") + x.AckFrequency = s.ReadUint64() + case "data_rate_index", "dataRateIndex": + s.AddField("data_rate_index") + x.DataRateIndex.UnmarshalProtoJSON(s) + } + }) +} + +// UnmarshalJSON unmarshals the BandDescription_RelayParameters_RelayWORChannel from JSON. +func (x *BandDescription_RelayParameters_RelayWORChannel) UnmarshalJSON(b []byte) error { + return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x) +} + +// MarshalProtoJSON marshals the BandDescription_RelayParameters message to JSON. +func (x *BandDescription_RelayParameters) MarshalProtoJSON(s *jsonplugin.MarshalState) { + if x == nil { + s.WriteNil() + return + } + s.WriteObjectStart() + var wroteField bool + if len(x.WorChannels) > 0 || s.HasField("wor_channels") { + s.WriteMoreIf(&wroteField) + s.WriteObjectField("wor_channels") + s.WriteArrayStart() + var wroteElement bool + for _, element := range x.WorChannels { + s.WriteMoreIf(&wroteElement) + element.MarshalProtoJSON(s.WithField("wor_channels")) + } + s.WriteArrayEnd() + } + s.WriteObjectEnd() +} + +// MarshalJSON marshals the BandDescription_RelayParameters to JSON. +func (x *BandDescription_RelayParameters) MarshalJSON() ([]byte, error) { + return jsonplugin.DefaultMarshalerConfig.Marshal(x) +} + +// UnmarshalProtoJSON unmarshals the BandDescription_RelayParameters message from JSON. +func (x *BandDescription_RelayParameters) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) { + if s.ReadNil() { + return + } + s.ReadObject(func(key string) { + switch key { + default: + s.ReadAny() // ignore unknown field + case "wor_channels", "worChannels": + s.AddField("wor_channels") + if s.ReadNil() { + x.WorChannels = nil + return + } + s.ReadArray(func() { + if s.ReadNil() { + x.WorChannels = append(x.WorChannels, nil) + return + } + v := &BandDescription_RelayParameters_RelayWORChannel{} + v.UnmarshalProtoJSON(s.WithField("wor_channels", false)) + if s.Err() != nil { + return + } + x.WorChannels = append(x.WorChannels, v) + }) + } + }) +} + +// UnmarshalJSON unmarshals the BandDescription_RelayParameters from JSON. +func (x *BandDescription_RelayParameters) UnmarshalJSON(b []byte) error { + return jsonplugin.DefaultUnmarshalerConfig.Unmarshal(b, x) +} + // MarshalProtoJSON marshals the BandDescription message to JSON. func (x *BandDescription) MarshalProtoJSON(s *jsonplugin.MarshalState) { if x == nil { @@ -553,6 +674,11 @@ func (x *BandDescription) MarshalProtoJSON(s *jsonplugin.MarshalState) { // NOTE: BandDescription_DwellTime does not seem to implement MarshalProtoJSON. golang.MarshalMessage(s, x.BootDwellTime) } + if x.Relay != nil || s.HasField("relay") { + s.WriteMoreIf(&wroteField) + s.WriteObjectField("relay") + x.Relay.MarshalProtoJSON(s.WithField("relay")) + } s.WriteObjectEnd() } @@ -771,6 +897,13 @@ func (x *BandDescription) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) { var v BandDescription_DwellTime golang.UnmarshalMessage(s, &v) x.BootDwellTime = &v + case "relay": + if s.ReadNil() { + x.Relay = nil + return + } + x.Relay = &BandDescription_RelayParameters{} + x.Relay.UnmarshalProtoJSON(s.WithField("relay", true)) } }) } diff --git a/sdk/js/generated/api.json b/sdk/js/generated/api.json index 5534d48095..d1ea3fd653 100644 --- a/sdk/js/generated/api.json +++ b/sdk/js/generated/api.json @@ -9195,6 +9195,18 @@ "isoneof": false, "oneofdecl": "", "defaultValue": "" + }, + { + "name": "relay", + "description": "", + "label": "", + "type": "RelayParameters", + "longType": "BandDescription.RelayParameters", + "fullType": "ttn.lorawan.v3.BandDescription.RelayParameters", + "ismap": false, + "isoneof": false, + "oneofdecl": "", + "defaultValue": "" } ] }, @@ -9390,6 +9402,78 @@ } ] }, + { + "name": "RelayParameters", + "longName": "BandDescription.RelayParameters", + "fullName": "ttn.lorawan.v3.BandDescription.RelayParameters", + "description": "", + "hasExtensions": false, + "hasFields": true, + "hasOneofs": false, + "extensions": [], + "fields": [ + { + "name": "wor_channels", + "description": "", + "label": "repeated", + "type": "RelayWORChannel", + "longType": "BandDescription.RelayParameters.RelayWORChannel", + "fullType": "ttn.lorawan.v3.BandDescription.RelayParameters.RelayWORChannel", + "ismap": false, + "isoneof": false, + "oneofdecl": "", + "defaultValue": "" + } + ] + }, + { + "name": "RelayWORChannel", + "longName": "BandDescription.RelayParameters.RelayWORChannel", + "fullName": "ttn.lorawan.v3.BandDescription.RelayParameters.RelayWORChannel", + "description": "", + "hasExtensions": false, + "hasFields": true, + "hasOneofs": false, + "extensions": [], + "fields": [ + { + "name": "frequency", + "description": "", + "label": "", + "type": "uint64", + "longType": "uint64", + "fullType": "uint64", + "ismap": false, + "isoneof": false, + "oneofdecl": "", + "defaultValue": "" + }, + { + "name": "ack_frequency", + "description": "", + "label": "", + "type": "uint64", + "longType": "uint64", + "fullType": "uint64", + "ismap": false, + "isoneof": false, + "oneofdecl": "", + "defaultValue": "" + }, + { + "name": "data_rate_index", + "description": "", + "label": "", + "type": "DataRateIndex", + "longType": "DataRateIndex", + "fullType": "ttn.lorawan.v3.DataRateIndex", + "ismap": false, + "isoneof": false, + "oneofdecl": "", + "defaultValue": "" + } + ] + }, { "name": "Rx2Parameters", "longName": "BandDescription.Rx2Parameters",