From 2ddd38bc963b215519e6f97a2ea70fea9bea8a5f Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 5 Feb 2019 13:07:24 +0100 Subject: [PATCH 01/40] make: Update protoc image version --- .make/protos/main.make | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.make/protos/main.make b/.make/protos/main.make index 614e2fdaad..9a57fdd210 100644 --- a/.make/protos/main.make +++ b/.make/protos/main.make @@ -18,7 +18,7 @@ API_PROTO_FILES = $(PWD)/api/'*.proto' PROTOC_OUT ?= /out -PROTOC_DOCKER_IMAGE ?= thethingsindustries/protoc:3.0.24 +PROTOC_DOCKER_IMAGE ?= thethingsindustries/protoc:3.0.26 PROTOC_DOCKER_ARGS = run --user `id -u` --rm \ --mount type=bind,src=$(PWD)/api,dst=$(PWD)/api \ --mount type=bind,src=$(PWD)/pkg/ttnpb,dst=$(PROTOC_OUT)/go.thethings.network/lorawan-stack/pkg/ttnpb \ From df6a0f0d0eb6b73a5543eeba581493ca269c4a09 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 5 Feb 2019 13:46:49 +0100 Subject: [PATCH 02/40] api: Add additional MACSettings --- api/api.md | 35 + api/api.swagger.json | 26 + api/end_device.proto | 15 +- pkg/ttnpb/end_device.pb.fm.go | 137 +++ pkg/ttnpb/end_device.pb.go | 1206 +++++++++++++++++++------- pkg/ttnpb/end_device.validator.pb.go | 22 + 6 files changed, 1126 insertions(+), 315 deletions(-) diff --git a/api/api.md b/api/api.md index abceff6646..1e223a5fe8 100644 --- a/api/api.md +++ b/api/api.md @@ -121,6 +121,8 @@ - [MACParameters](#ttn.lorawan.v3.MACParameters) - [MACParameters.Channel](#ttn.lorawan.v3.MACParameters.Channel) - [MACSettings](#ttn.lorawan.v3.MACSettings) + - [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) + - [MACSettings.RxDelayValue](#ttn.lorawan.v3.MACSettings.RxDelayValue) - [MACState](#ttn.lorawan.v3.MACState) - [MACState.JoinAccept](#ttn.lorawan.v3.MACState.JoinAccept) - [Session](#ttn.lorawan.v3.Session) @@ -1788,6 +1790,39 @@ This is used internally by the Network Server and is read only. | class_c_timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | Deadline for the device to respond to requests from the Network Server. | | status_time_periodicity | [google.protobuf.Duration](#google.protobuf.Duration) | | The interval after which a DevStatusReq MACCommand shall be sent. | | status_count_periodicity | [uint32](#uint32) | | Number of uplink messages after which a DevStatusReq MACCommand shall be sent. | +| rx1_delay | [MACSettings.RxDelayValue](#ttn.lorawan.v3.MACSettings.RxDelayValue) | | | +| rx2_data_rate_index | [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) | | | +| rx2_frequency | [google.protobuf.UInt64Value](#google.protobuf.UInt64Value) | | | + + + + + + + + +### MACSettings.DataRateIndexValue + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| value | [DataRateIndex](#ttn.lorawan.v3.DataRateIndex) | | | + + + + + + + + +### MACSettings.RxDelayValue + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| value | [RxDelay](#ttn.lorawan.v3.RxDelay) | | | diff --git a/api/api.swagger.json b/api/api.swagger.json index 8d38843719..047cf7de3c 100644 --- a/api/api.swagger.json +++ b/api/api.swagger.json @@ -4870,6 +4870,22 @@ } } }, + "MACSettingsDataRateIndexValue": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/v3DataRateIndex" + } + } + }, + "MACSettingsRxDelayValue": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/v3RxDelay" + } + } + }, "MACStateJoinAccept": { "type": "object", "properties": { @@ -7438,6 +7454,16 @@ "type": "integer", "format": "int64", "description": "Number of uplink messages after which a DevStatusReq MACCommand shall be sent." + }, + "rx1_delay": { + "$ref": "#/definitions/MACSettingsRxDelayValue" + }, + "rx2_data_rate_index": { + "$ref": "#/definitions/MACSettingsDataRateIndexValue" + }, + "rx2_frequency": { + "type": "string", + "format": "uint64" } } }, diff --git a/api/end_device.proto b/api/end_device.proto index dc81cb7bc3..9504c82de4 100644 --- a/api/end_device.proto +++ b/api/end_device.proto @@ -21,6 +21,7 @@ import "google/protobuf/duration.proto"; import "google/protobuf/field_mask.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; import "lorawan-stack/api/identifiers.proto"; import "lorawan-stack/api/join.proto"; import "lorawan-stack/api/keys.proto"; @@ -101,9 +102,9 @@ message MACParameters { // Channel can be used by device for uplink. bool enable_uplink = 5; } - // Configured uplink channels and optionally Rx1 frequency. repeated Channel channels = 16; + // Frequency of the class B ping slot (Hz). uint64 ping_slot_frequency = 17; // Data rate index of the class B ping slot. @@ -187,6 +188,18 @@ message MACSettings { google.protobuf.Duration status_time_periodicity = 5 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false]; // Number of uplink messages after which a DevStatusReq MACCommand shall be sent. uint32 status_count_periodicity = 6; + + message RxDelayValue { + RxDelay value = 1; + } + RxDelayValue rx1_delay = 7; + + message DataRateIndexValue { + DataRateIndex value = 1; + } + DataRateIndexValue rx2_data_rate_index = 8; + + google.protobuf.UInt64Value rx2_frequency = 9; } // MACState represents the state of MAC layer of the device. diff --git a/pkg/ttnpb/end_device.pb.fm.go b/pkg/ttnpb/end_device.pb.fm.go index a7fac8b1a5..f8f288e2ef 100644 --- a/pkg/ttnpb/end_device.pb.fm.go +++ b/pkg/ttnpb/end_device.pb.fm.go @@ -889,6 +889,11 @@ var MACSettingsFieldPathsNested = []string{ "adr_margin", "class_b_timeout", "class_c_timeout", + "rx1_delay", + "rx1_delay.value", + "rx2_data_rate_index", + "rx2_data_rate_index.value", + "rx2_frequency", "status_count_periodicity", "status_time_periodicity", "use_adr", @@ -898,6 +903,9 @@ var MACSettingsFieldPathsTopLevel = []string{ "adr_margin", "class_b_timeout", "class_c_timeout", + "rx1_delay", + "rx2_data_rate_index", + "rx2_frequency", "status_count_periodicity", "status_time_periodicity", "use_adr", @@ -966,6 +974,115 @@ func (dst *MACSettings) SetFields(src *MACSettings, paths ...string) error { var zero uint32 dst.StatusCountPeriodicity = zero } + case "rx1_delay": + if len(subs) > 0 { + newDst := dst.Rx1Delay + if newDst == nil { + newDst = &MACSettings_RxDelayValue{} + dst.Rx1Delay = newDst + } + var newSrc *MACSettings_RxDelayValue + if src != nil { + newSrc = src.Rx1Delay + } + if err := newDst.SetFields(newSrc, subs...); err != nil { + return err + } + } else { + if src != nil { + dst.Rx1Delay = src.Rx1Delay + } else { + dst.Rx1Delay = nil + } + } + case "rx2_data_rate_index": + if len(subs) > 0 { + newDst := dst.Rx2DataRateIndex + if newDst == nil { + newDst = &MACSettings_DataRateIndexValue{} + dst.Rx2DataRateIndex = newDst + } + var newSrc *MACSettings_DataRateIndexValue + if src != nil { + newSrc = src.Rx2DataRateIndex + } + if err := newDst.SetFields(newSrc, subs...); err != nil { + return err + } + } else { + if src != nil { + dst.Rx2DataRateIndex = src.Rx2DataRateIndex + } else { + dst.Rx2DataRateIndex = nil + } + } + case "rx2_frequency": + if len(subs) > 0 { + return fmt.Errorf("'rx2_frequency' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.Rx2Frequency = src.Rx2Frequency + } else { + dst.Rx2Frequency = nil + } + + default: + return fmt.Errorf("invalid field: '%s'", name) + } + } + return nil +} + +var MACSettings_RxDelayValueFieldPathsNested = []string{ + "value", +} + +var MACSettings_RxDelayValueFieldPathsTopLevel = []string{ + "value", +} + +func (dst *MACSettings_RxDelayValue) SetFields(src *MACSettings_RxDelayValue, paths ...string) error { + for name, subs := range _processPaths(append(paths[:0:0], paths...)) { + switch name { + case "value": + if len(subs) > 0 { + return fmt.Errorf("'value' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.Value = src.Value + } else { + var zero RxDelay + dst.Value = zero + } + + default: + return fmt.Errorf("invalid field: '%s'", name) + } + } + return nil +} + +var MACSettings_DataRateIndexValueFieldPathsNested = []string{ + "value", +} + +var MACSettings_DataRateIndexValueFieldPathsTopLevel = []string{ + "value", +} + +func (dst *MACSettings_DataRateIndexValue) SetFields(src *MACSettings_DataRateIndexValue, paths ...string) error { + for name, subs := range _processPaths(append(paths[:0:0], paths...)) { + switch name { + case "value": + if len(subs) > 0 { + return fmt.Errorf("'value' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.Value = src.Value + } else { + var zero DataRateIndex + dst.Value = zero + } default: return fmt.Errorf("invalid field: '%s'", name) @@ -1567,6 +1684,11 @@ var EndDeviceFieldPathsNested = []string{ "mac_settings.adr_margin", "mac_settings.class_b_timeout", "mac_settings.class_c_timeout", + "mac_settings.rx1_delay", + "mac_settings.rx1_delay.value", + "mac_settings.rx2_data_rate_index", + "mac_settings.rx2_data_rate_index.value", + "mac_settings.rx2_frequency", "mac_settings.status_count_periodicity", "mac_settings.status_time_periodicity", "mac_settings.use_adr", @@ -2531,6 +2653,11 @@ var CreateEndDeviceRequestFieldPathsNested = []string{ "end_device.mac_settings.adr_margin", "end_device.mac_settings.class_b_timeout", "end_device.mac_settings.class_c_timeout", + "end_device.mac_settings.rx1_delay", + "end_device.mac_settings.rx1_delay.value", + "end_device.mac_settings.rx2_data_rate_index", + "end_device.mac_settings.rx2_data_rate_index.value", + "end_device.mac_settings.rx2_frequency", "end_device.mac_settings.status_count_periodicity", "end_device.mac_settings.status_time_periodicity", "end_device.mac_settings.use_adr", @@ -2894,6 +3021,11 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{ "end_device.mac_settings.adr_margin", "end_device.mac_settings.class_b_timeout", "end_device.mac_settings.class_c_timeout", + "end_device.mac_settings.rx1_delay", + "end_device.mac_settings.rx1_delay.value", + "end_device.mac_settings.rx2_data_rate_index", + "end_device.mac_settings.rx2_data_rate_index.value", + "end_device.mac_settings.rx2_frequency", "end_device.mac_settings.status_count_periodicity", "end_device.mac_settings.status_time_periodicity", "end_device.mac_settings.use_adr", @@ -3410,6 +3542,11 @@ var SetEndDeviceRequestFieldPathsNested = []string{ "device.mac_settings.adr_margin", "device.mac_settings.class_b_timeout", "device.mac_settings.class_c_timeout", + "device.mac_settings.rx1_delay", + "device.mac_settings.rx1_delay.value", + "device.mac_settings.rx2_data_rate_index", + "device.mac_settings.rx2_data_rate_index.value", + "device.mac_settings.rx2_frequency", "device.mac_settings.status_count_periodicity", "device.mac_settings.status_time_periodicity", "device.mac_settings.use_adr", diff --git a/pkg/ttnpb/end_device.pb.go b/pkg/ttnpb/end_device.pb.go index bf845701f9..fdc891f535 100644 --- a/pkg/ttnpb/end_device.pb.go +++ b/pkg/ttnpb/end_device.pb.go @@ -62,7 +62,7 @@ var PowerState_value = map[string]int32{ } func (PowerState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{0} + return fileDescriptor_end_device_cd134bac00aa082e, []int{0} } type Session struct { @@ -87,7 +87,7 @@ type Session struct { func (m *Session) Reset() { *m = Session{} } func (*Session) ProtoMessage() {} func (*Session) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{0} + return fileDescriptor_end_device_cd134bac00aa082e, []int{0} } func (m *Session) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -199,7 +199,7 @@ type MACParameters struct { func (m *MACParameters) Reset() { *m = MACParameters{} } func (*MACParameters) ProtoMessage() {} func (*MACParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{1} + return fileDescriptor_end_device_cd134bac00aa082e, []int{1} } func (m *MACParameters) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -379,7 +379,7 @@ type MACParameters_Channel struct { func (m *MACParameters_Channel) Reset() { *m = MACParameters_Channel{} } func (*MACParameters_Channel) ProtoMessage() {} func (*MACParameters_Channel) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{1, 0} + return fileDescriptor_end_device_cd134bac00aa082e, []int{1, 0} } func (m *MACParameters_Channel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -456,7 +456,7 @@ type EndDeviceBrand struct { func (m *EndDeviceBrand) Reset() { *m = EndDeviceBrand{} } func (*EndDeviceBrand) ProtoMessage() {} func (*EndDeviceBrand) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{2} + return fileDescriptor_end_device_cd134bac00aa082e, []int{2} } func (m *EndDeviceBrand) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -524,7 +524,7 @@ type EndDeviceModel struct { func (m *EndDeviceModel) Reset() { *m = EndDeviceModel{} } func (*EndDeviceModel) ProtoMessage() {} func (*EndDeviceModel) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{3} + return fileDescriptor_end_device_cd134bac00aa082e, []int{3} } func (m *EndDeviceModel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -587,7 +587,7 @@ type EndDeviceVersionIdentifiers struct { func (m *EndDeviceVersionIdentifiers) Reset() { *m = EndDeviceVersionIdentifiers{} } func (*EndDeviceVersionIdentifiers) ProtoMessage() {} func (*EndDeviceVersionIdentifiers) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{4} + return fileDescriptor_end_device_cd134bac00aa082e, []int{4} } func (m *EndDeviceVersionIdentifiers) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -683,7 +683,7 @@ type EndDeviceVersion struct { func (m *EndDeviceVersion) Reset() { *m = EndDeviceVersion{} } func (*EndDeviceVersion) ProtoMessage() {} func (*EndDeviceVersion) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{5} + return fileDescriptor_end_device_cd134bac00aa082e, []int{5} } func (m *EndDeviceVersion) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -822,15 +822,18 @@ type MACSettings struct { // The interval after which a DevStatusReq MACCommand shall be sent. StatusTimePeriodicity time.Duration `protobuf:"bytes,5,opt,name=status_time_periodicity,json=statusTimePeriodicity,proto3,stdduration" json:"status_time_periodicity"` // Number of uplink messages after which a DevStatusReq MACCommand shall be sent. - StatusCountPeriodicity uint32 `protobuf:"varint,6,opt,name=status_count_periodicity,json=statusCountPeriodicity,proto3" json:"status_count_periodicity,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_sizecache int32 `json:"-"` + StatusCountPeriodicity uint32 `protobuf:"varint,6,opt,name=status_count_periodicity,json=statusCountPeriodicity,proto3" json:"status_count_periodicity,omitempty"` + Rx1Delay *MACSettings_RxDelayValue `protobuf:"bytes,7,opt,name=rx1_delay,json=rx1Delay,proto3" json:"rx1_delay,omitempty"` + Rx2DataRateIndex *MACSettings_DataRateIndexValue `protobuf:"bytes,8,opt,name=rx2_data_rate_index,json=rx2DataRateIndex,proto3" json:"rx2_data_rate_index,omitempty"` + Rx2Frequency *types.UInt64Value `protobuf:"bytes,9,opt,name=rx2_frequency,json=rx2Frequency,proto3" json:"rx2_frequency,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *MACSettings) Reset() { *m = MACSettings{} } func (*MACSettings) ProtoMessage() {} func (*MACSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{6} + return fileDescriptor_end_device_cd134bac00aa082e, []int{6} } func (m *MACSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -901,6 +904,117 @@ func (m *MACSettings) GetStatusCountPeriodicity() uint32 { return 0 } +func (m *MACSettings) GetRx1Delay() *MACSettings_RxDelayValue { + if m != nil { + return m.Rx1Delay + } + return nil +} + +func (m *MACSettings) GetRx2DataRateIndex() *MACSettings_DataRateIndexValue { + if m != nil { + return m.Rx2DataRateIndex + } + return nil +} + +func (m *MACSettings) GetRx2Frequency() *types.UInt64Value { + if m != nil { + return m.Rx2Frequency + } + return nil +} + +type MACSettings_RxDelayValue struct { + Value RxDelay `protobuf:"varint,1,opt,name=value,proto3,enum=ttn.lorawan.v3.RxDelay" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MACSettings_RxDelayValue) Reset() { *m = MACSettings_RxDelayValue{} } +func (*MACSettings_RxDelayValue) ProtoMessage() {} +func (*MACSettings_RxDelayValue) Descriptor() ([]byte, []int) { + return fileDescriptor_end_device_cd134bac00aa082e, []int{6, 0} +} +func (m *MACSettings_RxDelayValue) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MACSettings_RxDelayValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MACSettings_RxDelayValue.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *MACSettings_RxDelayValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_MACSettings_RxDelayValue.Merge(dst, src) +} +func (m *MACSettings_RxDelayValue) XXX_Size() int { + return m.Size() +} +func (m *MACSettings_RxDelayValue) XXX_DiscardUnknown() { + xxx_messageInfo_MACSettings_RxDelayValue.DiscardUnknown(m) +} + +var xxx_messageInfo_MACSettings_RxDelayValue proto.InternalMessageInfo + +func (m *MACSettings_RxDelayValue) GetValue() RxDelay { + if m != nil { + return m.Value + } + return RX_DELAY_0 +} + +type MACSettings_DataRateIndexValue struct { + Value DataRateIndex `protobuf:"varint,1,opt,name=value,proto3,enum=ttn.lorawan.v3.DataRateIndex" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MACSettings_DataRateIndexValue) Reset() { *m = MACSettings_DataRateIndexValue{} } +func (*MACSettings_DataRateIndexValue) ProtoMessage() {} +func (*MACSettings_DataRateIndexValue) Descriptor() ([]byte, []int) { + return fileDescriptor_end_device_cd134bac00aa082e, []int{6, 1} +} +func (m *MACSettings_DataRateIndexValue) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MACSettings_DataRateIndexValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MACSettings_DataRateIndexValue.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *MACSettings_DataRateIndexValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_MACSettings_DataRateIndexValue.Merge(dst, src) +} +func (m *MACSettings_DataRateIndexValue) XXX_Size() int { + return m.Size() +} +func (m *MACSettings_DataRateIndexValue) XXX_DiscardUnknown() { + xxx_messageInfo_MACSettings_DataRateIndexValue.DiscardUnknown(m) +} + +var xxx_messageInfo_MACSettings_DataRateIndexValue proto.InternalMessageInfo + +func (m *MACSettings_DataRateIndexValue) GetValue() DataRateIndex { + if m != nil { + return m.Value + } + return DATA_RATE_0 +} + // MACState represents the state of MAC layer of the device. // MACState is reset on each join for OTAA or ResetInd for ABP devices. // This is used internally by the Network Server and is read only. @@ -947,7 +1061,7 @@ type MACState struct { func (m *MACState) Reset() { *m = MACState{} } func (*MACState) ProtoMessage() {} func (*MACState) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{7} + return fileDescriptor_end_device_cd134bac00aa082e, []int{7} } func (m *MACState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1081,7 +1195,7 @@ type MACState_JoinAccept struct { func (m *MACState_JoinAccept) Reset() { *m = MACState_JoinAccept{} } func (*MACState_JoinAccept) ProtoMessage() {} func (*MACState_JoinAccept) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{7, 0} + return fileDescriptor_end_device_cd134bac00aa082e, []int{7, 0} } func (m *MACState_JoinAccept) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1278,7 +1392,7 @@ type EndDevice struct { func (m *EndDevice) Reset() { *m = EndDevice{} } func (*EndDevice) ProtoMessage() {} func (*EndDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{8} + return fileDescriptor_end_device_cd134bac00aa082e, []int{8} } func (m *EndDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1624,7 +1738,7 @@ type EndDevices struct { func (m *EndDevices) Reset() { *m = EndDevices{} } func (*EndDevices) ProtoMessage() {} func (*EndDevices) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{9} + return fileDescriptor_end_device_cd134bac00aa082e, []int{9} } func (m *EndDevices) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1669,7 +1783,7 @@ type CreateEndDeviceRequest struct { func (m *CreateEndDeviceRequest) Reset() { *m = CreateEndDeviceRequest{} } func (*CreateEndDeviceRequest) ProtoMessage() {} func (*CreateEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{10} + return fileDescriptor_end_device_cd134bac00aa082e, []int{10} } func (m *CreateEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1708,7 +1822,7 @@ type UpdateEndDeviceRequest struct { func (m *UpdateEndDeviceRequest) Reset() { *m = UpdateEndDeviceRequest{} } func (*UpdateEndDeviceRequest) ProtoMessage() {} func (*UpdateEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{11} + return fileDescriptor_end_device_cd134bac00aa082e, []int{11} } func (m *UpdateEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1754,7 +1868,7 @@ type GetEndDeviceRequest struct { func (m *GetEndDeviceRequest) Reset() { *m = GetEndDeviceRequest{} } func (*GetEndDeviceRequest) ProtoMessage() {} func (*GetEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{12} + return fileDescriptor_end_device_cd134bac00aa082e, []int{12} } func (m *GetEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1807,7 +1921,7 @@ type ListEndDevicesRequest struct { func (m *ListEndDevicesRequest) Reset() { *m = ListEndDevicesRequest{} } func (*ListEndDevicesRequest) ProtoMessage() {} func (*ListEndDevicesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{13} + return fileDescriptor_end_device_cd134bac00aa082e, []int{13} } func (m *ListEndDevicesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1874,7 +1988,7 @@ type SetEndDeviceRequest struct { func (m *SetEndDeviceRequest) Reset() { *m = SetEndDeviceRequest{} } func (*SetEndDeviceRequest) ProtoMessage() {} func (*SetEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f8ea6acb7b9cd33a, []int{14} + return fileDescriptor_end_device_cd134bac00aa082e, []int{14} } func (m *SetEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1934,6 +2048,10 @@ func init() { golang_proto.RegisterType((*EndDeviceVersion)(nil), "ttn.lorawan.v3.EndDeviceVersion") proto.RegisterType((*MACSettings)(nil), "ttn.lorawan.v3.MACSettings") golang_proto.RegisterType((*MACSettings)(nil), "ttn.lorawan.v3.MACSettings") + proto.RegisterType((*MACSettings_RxDelayValue)(nil), "ttn.lorawan.v3.MACSettings.RxDelayValue") + golang_proto.RegisterType((*MACSettings_RxDelayValue)(nil), "ttn.lorawan.v3.MACSettings.RxDelayValue") + proto.RegisterType((*MACSettings_DataRateIndexValue)(nil), "ttn.lorawan.v3.MACSettings.DataRateIndexValue") + golang_proto.RegisterType((*MACSettings_DataRateIndexValue)(nil), "ttn.lorawan.v3.MACSettings.DataRateIndexValue") proto.RegisterType((*MACState)(nil), "ttn.lorawan.v3.MACState") golang_proto.RegisterType((*MACState)(nil), "ttn.lorawan.v3.MACState") proto.RegisterType((*MACState_JoinAccept)(nil), "ttn.lorawan.v3.MACState.JoinAccept") @@ -2336,6 +2454,63 @@ func (this *MACSettings) Equal(that interface{}) bool { if this.StatusCountPeriodicity != that1.StatusCountPeriodicity { return false } + if !this.Rx1Delay.Equal(that1.Rx1Delay) { + return false + } + if !this.Rx2DataRateIndex.Equal(that1.Rx2DataRateIndex) { + return false + } + if !this.Rx2Frequency.Equal(that1.Rx2Frequency) { + return false + } + return true +} +func (this *MACSettings_RxDelayValue) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*MACSettings_RxDelayValue) + if !ok { + that2, ok := that.(MACSettings_RxDelayValue) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Value != that1.Value { + return false + } + return true +} +func (this *MACSettings_DataRateIndexValue) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*MACSettings_DataRateIndexValue) + if !ok { + that2, ok := that.(MACSettings_DataRateIndexValue) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Value != that1.Value { + return false + } return true } func (this *MACState) Equal(that interface{}) bool { @@ -3396,6 +3571,82 @@ func (m *MACSettings) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.StatusCountPeriodicity)) } + if m.Rx1Delay != nil { + dAtA[i] = 0x3a + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.Rx1Delay.Size())) + n10, err := m.Rx1Delay.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n10 + } + if m.Rx2DataRateIndex != nil { + dAtA[i] = 0x42 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.Rx2DataRateIndex.Size())) + n11, err := m.Rx2DataRateIndex.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n11 + } + if m.Rx2Frequency != nil { + dAtA[i] = 0x4a + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.Rx2Frequency.Size())) + n12, err := m.Rx2Frequency.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n12 + } + return i, nil +} + +func (m *MACSettings_RxDelayValue) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MACSettings_RxDelayValue) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Value != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.Value)) + } + return i, nil +} + +func (m *MACSettings_DataRateIndexValue) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MACSettings_DataRateIndexValue) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Value != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.Value)) + } return i, nil } @@ -3417,19 +3668,19 @@ func (m *MACState) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.CurrentParameters.Size())) - n10, err := m.CurrentParameters.MarshalTo(dAtA[i:]) + n13, err := m.CurrentParameters.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n10 + i += n13 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.DesiredParameters.Size())) - n11, err := m.DesiredParameters.MarshalTo(dAtA[i:]) + n14, err := m.DesiredParameters.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n11 + i += n14 if m.DeviceClass != 0 { dAtA[i] = 0x18 i++ @@ -3444,11 +3695,11 @@ func (m *MACState) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastConfirmedDownlinkAt))) - n12, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastConfirmedDownlinkAt, dAtA[i:]) + n15, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastConfirmedDownlinkAt, dAtA[i:]) if err != nil { return 0, err } - i += n12 + i += n15 } if m.LastDevStatusFCntUp != 0 { dAtA[i] = 0x30 @@ -3464,11 +3715,11 @@ func (m *MACState) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x42 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.PendingApplicationDownlink.Size())) - n13, err := m.PendingApplicationDownlink.MarshalTo(dAtA[i:]) + n16, err := m.PendingApplicationDownlink.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n13 + i += n16 } if len(m.QueuedResponses) > 0 { for _, msg := range m.QueuedResponses { @@ -3498,21 +3749,21 @@ func (m *MACState) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x5a i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.QueuedJoinAccept.Size())) - n14, err := m.QueuedJoinAccept.MarshalTo(dAtA[i:]) + n17, err := m.QueuedJoinAccept.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n14 + i += n17 } if m.PendingJoinRequest != nil { dAtA[i] = 0x62 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.PendingJoinRequest.Size())) - n15, err := m.PendingJoinRequest.MarshalTo(dAtA[i:]) + n18, err := m.PendingJoinRequest.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n15 + i += n18 } if m.RxWindowsAvailable { dAtA[i] = 0x68 @@ -3551,19 +3802,19 @@ func (m *MACState_JoinAccept) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Request.Size())) - n16, err := m.Request.MarshalTo(dAtA[i:]) + n19, err := m.Request.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n16 + i += n19 dAtA[i] = 0x1a i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Keys.Size())) - n17, err := m.Keys.MarshalTo(dAtA[i:]) + n20, err := m.Keys.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n17 + i += n20 return i, nil } @@ -3585,27 +3836,27 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.EndDeviceIdentifiers.Size())) - n18, err := m.EndDeviceIdentifiers.MarshalTo(dAtA[i:]) + n21, err := m.EndDeviceIdentifiers.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n18 + i += n21 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt))) - n19, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i:]) + n22, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n22 dAtA[i] = 0x1a i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.UpdatedAt))) - n20, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.UpdatedAt, dAtA[i:]) + n23, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.UpdatedAt, dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n23 if len(m.Name) > 0 { dAtA[i] = 0x22 i++ @@ -3639,11 +3890,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x3a i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.VersionIDs.Size())) - n21, err := m.VersionIDs.MarshalTo(dAtA[i:]) + n24, err := m.VersionIDs.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n24 } if len(m.ServiceProfileID) > 0 { dAtA[i] = 0x42 @@ -3689,11 +3940,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(v.Size())) - n22, err := v.MarshalTo(dAtA[i:]) + n25, err := v.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n22 + i += n25 } } } @@ -3743,11 +3994,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.DefaultMACParameters.Size())) - n23, err := m.DefaultMACParameters.MarshalTo(dAtA[i:]) + n26, err := m.DefaultMACParameters.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n26 } if m.MinFrequency != 0 { dAtA[i] = 0x98 @@ -3817,11 +4068,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.RootKeys.Size())) - n24, err := m.RootKeys.MarshalTo(dAtA[i:]) + n27, err := m.RootKeys.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n27 } if m.NetID != nil { dAtA[i] = 0xd2 @@ -3829,11 +4080,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.NetID.Size())) - n25, err := m.NetID.MarshalTo(dAtA[i:]) + n28, err := m.NetID.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n28 } if m.MACSettings != nil { dAtA[i] = 0xda @@ -3841,11 +4092,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.MACSettings.Size())) - n26, err := m.MACSettings.MarshalTo(dAtA[i:]) + n29, err := m.MACSettings.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n29 } if m.MACState != nil { dAtA[i] = 0xe2 @@ -3853,11 +4104,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.MACState.Size())) - n27, err := m.MACState.MarshalTo(dAtA[i:]) + n30, err := m.MACState.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n27 + i += n30 } if m.Session != nil { dAtA[i] = 0xea @@ -3865,11 +4116,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Session.Size())) - n28, err := m.Session.MarshalTo(dAtA[i:]) + n31, err := m.Session.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n28 + i += n31 } if m.PendingSession != nil { dAtA[i] = 0xf2 @@ -3877,11 +4128,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.PendingSession.Size())) - n29, err := m.PendingSession.MarshalTo(dAtA[i:]) + n32, err := m.PendingSession.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n29 + i += n32 } if m.LastDevNonce != 0 { dAtA[i] = 0xf8 @@ -3891,23 +4142,23 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintEndDevice(dAtA, i, uint64(m.LastDevNonce)) } if len(m.UsedDevNonces) > 0 { - dAtA31 := make([]byte, len(m.UsedDevNonces)*10) - var j30 int + dAtA34 := make([]byte, len(m.UsedDevNonces)*10) + var j33 int for _, num := range m.UsedDevNonces { for num >= 1<<7 { - dAtA31[j30] = uint8(uint64(num)&0x7f | 0x80) + dAtA34[j33] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j30++ + j33++ } - dAtA31[j30] = uint8(num) - j30++ + dAtA34[j33] = uint8(num) + j33++ } dAtA[i] = 0x82 i++ dAtA[i] = 0x2 i++ - i = encodeVarintEndDevice(dAtA, i, uint64(j30)) - i += copy(dAtA[i:], dAtA31[:j30]) + i = encodeVarintEndDevice(dAtA, i, uint64(j33)) + i += copy(dAtA[i:], dAtA34[:j33]) } if m.LastJoinNonce != 0 { dAtA[i] = 0x88 @@ -3936,11 +4187,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2 i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastDevStatusReceivedAt))) - n32, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastDevStatusReceivedAt, dAtA[i:]) + n35, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastDevStatusReceivedAt, dAtA[i:]) if err != nil { return 0, err } - i += n32 + i += n35 } if m.PowerState != 0 { dAtA[i] = 0xa8 @@ -4026,11 +4277,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Formatters.Size())) - n33, err := m.Formatters.MarshalTo(dAtA[i:]) + n36, err := m.Formatters.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n33 + i += n36 } if len(m.ProvisionerID) > 0 { dAtA[i] = 0xea @@ -4046,11 +4297,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.ProvisioningData.Size())) - n34, err := m.ProvisioningData.MarshalTo(dAtA[i:]) + n37, err := m.ProvisioningData.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n34 + i += n37 } return i, nil } @@ -4103,11 +4354,11 @@ func (m *CreateEndDeviceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.EndDevice.Size())) - n35, err := m.EndDevice.MarshalTo(dAtA[i:]) + n38, err := m.EndDevice.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n35 + i += n38 return i, nil } @@ -4129,19 +4380,19 @@ func (m *UpdateEndDeviceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.EndDevice.Size())) - n36, err := m.EndDevice.MarshalTo(dAtA[i:]) + n39, err := m.EndDevice.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n36 + i += n39 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.FieldMask.Size())) - n37, err := m.FieldMask.MarshalTo(dAtA[i:]) + n40, err := m.FieldMask.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n37 + i += n40 return i, nil } @@ -4163,19 +4414,19 @@ func (m *GetEndDeviceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.EndDeviceIdentifiers.Size())) - n38, err := m.EndDeviceIdentifiers.MarshalTo(dAtA[i:]) + n41, err := m.EndDeviceIdentifiers.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n38 + i += n41 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.FieldMask.Size())) - n39, err := m.FieldMask.MarshalTo(dAtA[i:]) + n42, err := m.FieldMask.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n39 + i += n42 return i, nil } @@ -4197,19 +4448,19 @@ func (m *ListEndDevicesRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.ApplicationIdentifiers.Size())) - n40, err := m.ApplicationIdentifiers.MarshalTo(dAtA[i:]) + n43, err := m.ApplicationIdentifiers.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n40 + i += n43 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.FieldMask.Size())) - n41, err := m.FieldMask.MarshalTo(dAtA[i:]) + n44, err := m.FieldMask.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n41 + i += n44 if len(m.Order) > 0 { dAtA[i] = 0x1a i++ @@ -4247,19 +4498,19 @@ func (m *SetEndDeviceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Device.Size())) - n42, err := m.Device.MarshalTo(dAtA[i:]) + n45, err := m.Device.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n42 + i += n45 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.FieldMask.Size())) - n43, err := m.FieldMask.MarshalTo(dAtA[i:]) + n46, err := m.FieldMask.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n43 + i += n46 return i, nil } @@ -4336,6 +4587,31 @@ func NewPopulatedMACSettings(r randyEndDevice, easy bool) *MACSettings { v7 := github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy) this.StatusTimePeriodicity = *v7 this.StatusCountPeriodicity = r.Uint32() + if r.Intn(10) != 0 { + this.Rx1Delay = NewPopulatedMACSettings_RxDelayValue(r, easy) + } + if r.Intn(10) != 0 { + this.Rx2DataRateIndex = NewPopulatedMACSettings_DataRateIndexValue(r, easy) + } + if r.Intn(10) != 0 { + this.Rx2Frequency = types.NewPopulatedUInt64Value(r, easy) + } + if !easy && r.Intn(10) != 0 { + } + return this +} + +func NewPopulatedMACSettings_RxDelayValue(r randyEndDevice, easy bool) *MACSettings_RxDelayValue { + this := &MACSettings_RxDelayValue{} + this.Value = RxDelay([]int32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}[r.Intn(16)]) + if !easy && r.Intn(10) != 0 { + } + return this +} + +func NewPopulatedMACSettings_DataRateIndexValue(r randyEndDevice, easy bool) *MACSettings_DataRateIndexValue { + this := &MACSettings_DataRateIndexValue{} + this.Value = DataRateIndex([]int32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}[r.Intn(16)]) if !easy && r.Intn(10) != 0 { } return this @@ -4770,6 +5046,42 @@ func (m *MACSettings) Size() (n int) { if m.StatusCountPeriodicity != 0 { n += 1 + sovEndDevice(uint64(m.StatusCountPeriodicity)) } + if m.Rx1Delay != nil { + l = m.Rx1Delay.Size() + n += 1 + l + sovEndDevice(uint64(l)) + } + if m.Rx2DataRateIndex != nil { + l = m.Rx2DataRateIndex.Size() + n += 1 + l + sovEndDevice(uint64(l)) + } + if m.Rx2Frequency != nil { + l = m.Rx2Frequency.Size() + n += 1 + l + sovEndDevice(uint64(l)) + } + return n +} + +func (m *MACSettings_RxDelayValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Value != 0 { + n += 1 + sovEndDevice(uint64(m.Value)) + } + return n +} + +func (m *MACSettings_DataRateIndexValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Value != 0 { + n += 1 + sovEndDevice(uint64(m.Value)) + } return n } @@ -5272,6 +5584,29 @@ func (this *MACSettings) String() string { `ClassCTimeout:` + strings.Replace(strings.Replace(this.ClassCTimeout.String(), "Duration", "types.Duration", 1), `&`, ``, 1) + `,`, `StatusTimePeriodicity:` + strings.Replace(strings.Replace(this.StatusTimePeriodicity.String(), "Duration", "types.Duration", 1), `&`, ``, 1) + `,`, `StatusCountPeriodicity:` + fmt.Sprintf("%v", this.StatusCountPeriodicity) + `,`, + `Rx1Delay:` + strings.Replace(fmt.Sprintf("%v", this.Rx1Delay), "MACSettings_RxDelayValue", "MACSettings_RxDelayValue", 1) + `,`, + `Rx2DataRateIndex:` + strings.Replace(fmt.Sprintf("%v", this.Rx2DataRateIndex), "MACSettings_DataRateIndexValue", "MACSettings_DataRateIndexValue", 1) + `,`, + `Rx2Frequency:` + strings.Replace(fmt.Sprintf("%v", this.Rx2Frequency), "UInt64Value", "types.UInt64Value", 1) + `,`, + `}`, + }, "") + return s +} +func (this *MACSettings_RxDelayValue) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MACSettings_RxDelayValue{`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `}`, + }, "") + return s +} +func (this *MACSettings_DataRateIndexValue) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MACSettings_DataRateIndexValue{`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, `}`, }, "") return s @@ -7282,6 +7617,243 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { break } } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Rx1Delay", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Rx1Delay == nil { + m.Rx1Delay = &MACSettings_RxDelayValue{} + } + if err := m.Rx1Delay.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Rx2DataRateIndex", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Rx2DataRateIndex == nil { + m.Rx2DataRateIndex = &MACSettings_DataRateIndexValue{} + } + if err := m.Rx2DataRateIndex.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Rx2Frequency", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Rx2Frequency == nil { + m.Rx2Frequency = &types.UInt64Value{} + } + if err := m.Rx2Frequency.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEndDevice(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthEndDevice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MACSettings_RxDelayValue) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RxDelayValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RxDelayValue: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + m.Value = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Value |= (RxDelay(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipEndDevice(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthEndDevice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MACSettings_DataRateIndexValue) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DataRateIndexValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DataRateIndexValue: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + m.Value = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Value |= (DataRateIndex(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipEndDevice(dAtA[iNdEx:]) @@ -10111,227 +10683,233 @@ var ( ) func init() { - proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_f8ea6acb7b9cd33a) + proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_cd134bac00aa082e) } func init() { - golang_proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_f8ea6acb7b9cd33a) -} - -var fileDescriptor_end_device_f8ea6acb7b9cd33a = []byte{ - // 3434 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5a, 0x4d, 0x6c, 0x1c, 0xc7, - 0x95, 0x9e, 0x1e, 0x52, 0xe4, 0x4c, 0x0d, 0xe7, 0xaf, 0x48, 0x49, 0x6d, 0xda, 0xee, 0xa1, 0x29, - 0xd9, 0xa1, 0x1d, 0x71, 0x28, 0x51, 0xf6, 0xc6, 0x51, 0xb2, 0x90, 0x67, 0x38, 0x54, 0x4c, 0x9b, - 0xa2, 0xb8, 0x25, 0xc9, 0x5a, 0xc7, 0x91, 0x1b, 0xc5, 0xe9, 0xe2, 0xb0, 0xcd, 0x99, 0xee, 0x4e, - 0x55, 0x0d, 0x39, 0xdc, 0x1f, 0x20, 0x97, 0x05, 0x72, 0x4b, 0x16, 0xd8, 0x05, 0x72, 0x59, 0x20, - 0x58, 0xec, 0x02, 0xc1, 0x62, 0x0f, 0x39, 0xfa, 0x98, 0xa3, 0x8f, 0x3e, 0x06, 0x39, 0x8c, 0xa2, - 0xe1, 0x25, 0xc7, 0x00, 0x7b, 0xc9, 0x71, 0x51, 0x3f, 0xfd, 0x33, 0x3f, 0x94, 0x49, 0x7b, 0xbd, - 0x17, 0xa2, 0xfb, 0xbd, 0xef, 0x7d, 0xfd, 0xaa, 0x5e, 0xd5, 0xab, 0xf7, 0x6a, 0x08, 0x96, 0xdb, - 0x3e, 0xc5, 0xc7, 0xd8, 0x5b, 0x65, 0x1c, 0x37, 0x0f, 0xd7, 0x70, 0xe0, 0xae, 0x11, 0xcf, 0xb1, - 0x1d, 0x72, 0xe4, 0x36, 0x49, 0x35, 0xa0, 0x3e, 0xf7, 0x61, 0x81, 0x73, 0xaf, 0xaa, 0x71, 0xd5, - 0xa3, 0xdb, 0x8b, 0xab, 0x2d, 0x97, 0x1f, 0x74, 0xf7, 0xaa, 0x4d, 0xbf, 0xb3, 0xd6, 0xf2, 0x5b, - 0xfe, 0x9a, 0x84, 0xed, 0x75, 0xf7, 0xe5, 0x9b, 0x7c, 0x91, 0x4f, 0xca, 0x7c, 0xf1, 0xaf, 0x12, - 0xf0, 0xce, 0xb1, 0xcb, 0x0f, 0xfd, 0xe3, 0xb5, 0x96, 0xbf, 0x2a, 0x95, 0xab, 0x47, 0xb8, 0xed, - 0x3a, 0x98, 0xfb, 0x94, 0xad, 0x45, 0x8f, 0xda, 0xee, 0x95, 0x96, 0xef, 0xb7, 0xda, 0x44, 0xfa, - 0x84, 0x3d, 0xcf, 0xe7, 0x98, 0xbb, 0xbe, 0xc7, 0xb4, 0xd6, 0xd2, 0xda, 0xe8, 0xdb, 0x4e, 0x97, - 0x4a, 0x80, 0xd6, 0x2f, 0x8d, 0xea, 0xf7, 0x5d, 0xd2, 0x76, 0xec, 0x0e, 0x66, 0x87, 0x23, 0xfc, - 0x11, 0x82, 0x71, 0xda, 0x6d, 0x72, 0xad, 0xad, 0x8c, 0x6a, 0xb9, 0xdb, 0x21, 0x8c, 0xe3, 0x4e, - 0xa0, 0x01, 0xd7, 0xc6, 0x67, 0xce, 0x75, 0x88, 0xc7, 0xdd, 0x7d, 0x97, 0xd0, 0xd0, 0xcb, 0x57, - 0xc6, 0x41, 0x9f, 0xf9, 0xae, 0x77, 0xb6, 0xf6, 0x90, 0x9c, 0x84, 0xb6, 0x95, 0x71, 0x6d, 0x18, - 0x04, 0x3d, 0xc4, 0x71, 0x40, 0x87, 0x30, 0x86, 0x5b, 0x84, 0xbd, 0x08, 0xc1, 0xb1, 0x83, 0x39, - 0x56, 0x88, 0xe5, 0x5f, 0x4c, 0x81, 0xd9, 0x87, 0x84, 0x31, 0xd7, 0xf7, 0xe0, 0x13, 0x90, 0x71, - 0xc8, 0x91, 0x8d, 0x1d, 0x87, 0x9a, 0xe9, 0x25, 0x63, 0x65, 0xae, 0xfe, 0xc3, 0x2f, 0xfa, 0x95, - 0xd4, 0x1f, 0xfa, 0x95, 0xb7, 0x5b, 0x7e, 0x95, 0x1f, 0x10, 0x7e, 0xe0, 0x7a, 0x2d, 0x56, 0xf5, - 0x08, 0x3f, 0xf6, 0xe9, 0xe1, 0xda, 0x30, 0x79, 0x70, 0xd8, 0x5a, 0xe3, 0x27, 0x01, 0x61, 0xd5, - 0x06, 0x39, 0xaa, 0x39, 0x0e, 0x45, 0xb3, 0x8e, 0x7a, 0x80, 0xdf, 0x07, 0xd3, 0x62, 0x5c, 0xe6, - 0xd4, 0x92, 0xb1, 0x92, 0x5b, 0x7f, 0xb9, 0x3a, 0xbc, 0x9e, 0xaa, 0xfa, 0xfb, 0x1f, 0x92, 0x13, - 0x56, 0xcf, 0x88, 0x2f, 0x7e, 0xd9, 0xaf, 0x18, 0x48, 0x9a, 0xc0, 0xd7, 0x40, 0xbe, 0x8d, 0x19, - 0xb7, 0xf7, 0xed, 0xa6, 0xc7, 0xed, 0x6e, 0x60, 0x4e, 0x2f, 0x19, 0x2b, 0x79, 0x04, 0x84, 0xf0, - 0xde, 0x86, 0xc7, 0x1f, 0x07, 0x70, 0x05, 0x94, 0x25, 0xc4, 0xd3, 0x20, 0xc7, 0x3f, 0xf6, 0xcc, - 0x4b, 0x12, 0x26, 0x6d, 0x77, 0x04, 0xae, 0xe1, 0x1f, 0x7b, 0x11, 0x12, 0x27, 0x91, 0x33, 0x31, - 0xb2, 0x16, 0x21, 0xab, 0x60, 0x41, 0x22, 0x9b, 0xbe, 0xb7, 0x9f, 0x04, 0xcf, 0x4a, 0x70, 0x49, - 0xe8, 0x36, 0x7c, 0x6f, 0x3f, 0xc2, 0x6f, 0x00, 0xc0, 0x38, 0xa6, 0x9c, 0x38, 0x36, 0xe6, 0x66, - 0x46, 0x8e, 0x73, 0xb1, 0xaa, 0x96, 0x50, 0x35, 0x5c, 0x42, 0xd5, 0x47, 0xe1, 0x12, 0x52, 0xc3, - 0xfc, 0xe5, 0xb3, 0x8a, 0x81, 0xb2, 0xda, 0xae, 0xc6, 0x3f, 0x98, 0xce, 0x18, 0xa5, 0xf4, 0xf2, - 0xb3, 0x1c, 0xc8, 0xdf, 0xaf, 0x6d, 0xec, 0x62, 0x8a, 0x3b, 0x84, 0x13, 0xca, 0xe0, 0x1b, 0x20, - 0xd3, 0xc1, 0x3d, 0x9b, 0xb8, 0x34, 0x30, 0x8d, 0x25, 0x63, 0x25, 0x5d, 0xcf, 0x0d, 0xfa, 0x95, - 0xd9, 0xfb, 0xb8, 0xb7, 0xb9, 0x85, 0x76, 0xd1, 0x6c, 0x07, 0xf7, 0x36, 0x5d, 0x1a, 0xc0, 0xb7, - 0x40, 0xb9, 0x1b, 0xb4, 0x5d, 0xef, 0xd0, 0x76, 0x8e, 0x49, 0xbb, 0x6d, 0x8b, 0x15, 0x2b, 0x03, - 0x99, 0x41, 0x45, 0xa5, 0x68, 0x08, 0xb9, 0xf0, 0x02, 0x56, 0xc1, 0xbc, 0x18, 0xd0, 0x28, 0x7a, - 0x4a, 0xa2, 0xcb, 0xa1, 0x2a, 0xc6, 0xef, 0x81, 0x79, 0xec, 0x50, 0x5b, 0xac, 0x1c, 0x9b, 0x62, - 0x4e, 0x6c, 0xd7, 0x73, 0x48, 0x4f, 0x46, 0xa3, 0xb0, 0xfe, 0xea, 0x68, 0x44, 0x1b, 0x98, 0x63, - 0x84, 0x39, 0xd9, 0x12, 0xa0, 0xfa, 0xc2, 0xa0, 0x5f, 0x29, 0xd5, 0x1a, 0x68, 0x48, 0x8a, 0x4a, - 0xd8, 0xa1, 0x43, 0x12, 0xf8, 0x1e, 0x80, 0xe2, 0x1b, 0xbc, 0x67, 0x07, 0xfe, 0x31, 0xa1, 0xfa, - 0x13, 0x32, 0x92, 0xf5, 0xf9, 0x41, 0xbf, 0x52, 0xac, 0x35, 0xd0, 0xa3, 0xde, 0xae, 0xd0, 0x29, - 0x8a, 0x22, 0x76, 0x68, 0x52, 0x00, 0x6f, 0x82, 0x39, 0xc1, 0xe0, 0xed, 0xd9, 0x9c, 0x62, 0x8f, - 0xa9, 0xd8, 0xd6, 0x0b, 0x83, 0x7e, 0x05, 0xd4, 0x1a, 0x68, 0x67, 0xef, 0x91, 0x90, 0x22, 0x80, - 0x1d, 0xaa, 0x9f, 0xe1, 0x6d, 0x90, 0x17, 0x16, 0xb8, 0x79, 0x68, 0xb7, 0xdd, 0x8e, 0xcb, 0x55, - 0x84, 0xeb, 0xc5, 0x41, 0xbf, 0x92, 0xab, 0x35, 0x50, 0xad, 0x79, 0xb8, 0x2d, 0xc4, 0x28, 0x87, - 0x1d, 0x1a, 0xbe, 0x24, 0x8d, 0x1c, 0xd2, 0xc6, 0x27, 0x32, 0xe0, 0x43, 0x46, 0x0d, 0x21, 0x0e, - 0x8d, 0xe4, 0x0b, 0x7c, 0x1b, 0x64, 0x69, 0xef, 0x96, 0x36, 0xc8, 0xca, 0x79, 0xbb, 0x3a, 0x3a, - 0x6f, 0xa8, 0xa7, 0x0c, 0x33, 0xb4, 0x77, 0x4b, 0x59, 0xad, 0x81, 0x05, 0x69, 0x15, 0xcd, 0xbb, - 0xbf, 0xbf, 0xcf, 0x08, 0x37, 0x81, 0x5c, 0x88, 0x65, 0x81, 0xd3, 0x73, 0xf8, 0x40, 0x2a, 0xe0, - 0x36, 0x98, 0xa7, 0xbd, 0xf5, 0xb1, 0x40, 0xe5, 0xce, 0x11, 0x28, 0x54, 0xa2, 0xbd, 0xf5, 0xe1, - 0x90, 0x5c, 0x03, 0x79, 0xc1, 0xb6, 0x4f, 0xc9, 0x4f, 0xbb, 0xc4, 0x6b, 0x9e, 0x98, 0x73, 0x4b, - 0xc6, 0xca, 0x34, 0x9a, 0xa3, 0xbd, 0xf5, 0x7b, 0xa1, 0x0c, 0xfe, 0x18, 0x5c, 0xa5, 0x44, 0xa4, - 0x35, 0xb9, 0x86, 0xec, 0x80, 0x50, 0xd7, 0x77, 0xdc, 0xa6, 0xcb, 0x4f, 0xcc, 0xbc, 0xfc, 0xec, - 0xf2, 0xd8, 0x38, 0x25, 0x5c, 0x2c, 0xac, 0xcd, 0x5e, 0xe0, 0x7b, 0xc4, 0xe3, 0xe8, 0x32, 0x8d, - 0x64, 0xbb, 0x31, 0x01, 0x7c, 0x0a, 0x4c, 0xcd, 0xdd, 0xf4, 0xbb, 0x1e, 0x1f, 0x22, 0x2f, 0x48, - 0xf2, 0x6b, 0x93, 0xc9, 0x37, 0x04, 0x3c, 0x62, 0xbf, 0x42, 0x63, 0x61, 0x92, 0x7e, 0x0b, 0x14, - 0xc4, 0xd6, 0x72, 0xba, 0xfc, 0xc4, 0x6e, 0x9e, 0x34, 0xdb, 0xc4, 0x2c, 0x4e, 0x26, 0xad, 0xb5, - 0x5a, 0x94, 0xb4, 0x30, 0x27, 0x4e, 0xa3, 0xcb, 0x4f, 0x36, 0x04, 0x14, 0xcd, 0x75, 0x70, 0x2f, - 0x7a, 0x83, 0x35, 0x90, 0x69, 0x1e, 0x60, 0xcf, 0x23, 0x6d, 0x66, 0x96, 0x96, 0xa6, 0x56, 0x72, - 0xeb, 0xaf, 0x8f, 0x92, 0x0c, 0x6d, 0xeb, 0xea, 0x86, 0x42, 0xa3, 0xc8, 0x4c, 0x6c, 0xca, 0xc0, - 0xf5, 0x5a, 0x36, 0x6b, 0xfb, 0x3c, 0x31, 0xe7, 0x65, 0x39, 0xe7, 0x65, 0xa1, 0x7a, 0xd8, 0xf6, - 0x79, 0x3c, 0xf1, 0x4f, 0xc0, 0x4b, 0x31, 0x7e, 0x34, 0xe2, 0xf0, 0x3c, 0x11, 0xbf, 0x1c, 0x92, - 0x0e, 0x87, 0xfd, 0x4d, 0x50, 0xda, 0x23, 0xb8, 0xe9, 0x7b, 0x09, 0x2f, 0xe6, 0xa5, 0x17, 0x45, - 0x25, 0x8f, 0x7c, 0x58, 0xfc, 0xaf, 0x34, 0x98, 0xd5, 0x23, 0x11, 0x66, 0x3a, 0x01, 0xc5, 0x66, - 0x86, 0x32, 0x53, 0xf2, 0xd8, 0xf5, 0x55, 0x00, 0xa3, 0xfc, 0x13, 0x83, 0xd3, 0x6a, 0xa4, 0xa1, - 0x26, 0x86, 0x6f, 0x83, 0xf9, 0x8e, 0xeb, 0x8d, 0x8d, 0x71, 0xea, 0x5c, 0xab, 0xba, 0xe3, 0x7a, - 0xc3, 0xc3, 0x13, 0x6c, 0x22, 0xea, 0x5f, 0x23, 0x99, 0xa1, 0x92, 0x08, 0xfa, 0xe8, 0x1e, 0x21, - 0x1e, 0xde, 0x6b, 0x13, 0x5b, 0x0d, 0x52, 0x66, 0xac, 0x0c, 0x9a, 0x53, 0xc2, 0xc7, 0x52, 0x76, - 0x67, 0xfa, 0xf3, 0x5f, 0x57, 0x52, 0xea, 0xef, 0x72, 0x07, 0x14, 0x36, 0x3d, 0xa7, 0x21, 0x4b, - 0xac, 0x3a, 0xc5, 0x9e, 0x03, 0xaf, 0x80, 0xb4, 0xeb, 0xc8, 0xa9, 0xca, 0xd6, 0x67, 0x06, 0xfd, - 0x4a, 0x7a, 0xab, 0x81, 0xd2, 0xae, 0x03, 0x21, 0x98, 0xf6, 0xb0, 0x4e, 0xe2, 0x59, 0x24, 0x9f, - 0xe1, 0x4b, 0x60, 0xaa, 0x4b, 0xdb, 0x72, 0xe8, 0xd9, 0xfa, 0xec, 0xa0, 0x5f, 0x99, 0x7a, 0x8c, - 0xb6, 0x91, 0x90, 0xc1, 0x05, 0x70, 0xa9, 0xed, 0xb7, 0x7c, 0x66, 0x4e, 0x2f, 0x4d, 0xad, 0x64, - 0x91, 0x7a, 0x59, 0x76, 0x12, 0x9f, 0xbb, 0xef, 0x3b, 0xa4, 0x2d, 0x0e, 0x94, 0x3d, 0xf1, 0x5d, - 0x3b, 0xfa, 0xa8, 0x3c, 0x50, 0xa4, 0x2f, 0x5b, 0x0d, 0x34, 0x2b, 0x95, 0x5b, 0xa1, 0x5b, 0xe9, - 0x33, 0xdd, 0x9a, 0x8a, 0xdd, 0x5a, 0xfe, 0xd7, 0x34, 0x78, 0x39, 0xfa, 0xcc, 0x47, 0x84, 0x8a, - 0x13, 0x7d, 0x2b, 0xae, 0x87, 0xe0, 0x83, 0xb1, 0x6f, 0xbe, 0x9d, 0xf8, 0xe6, 0xe0, 0x59, 0xe5, - 0x75, 0xf0, 0xda, 0xa7, 0x9f, 0xe0, 0xd5, 0xbf, 0xbb, 0xb9, 0xfa, 0xfd, 0xa7, 0x2b, 0x77, 0xef, - 0x7c, 0xb2, 0xfa, 0xf4, 0x6e, 0xf8, 0xfa, 0xe6, 0xdf, 0xaf, 0xdf, 0xf8, 0xc7, 0xeb, 0xff, 0xf0, - 0xe9, 0xf5, 0xde, 0xeb, 0xb1, 0x73, 0x0f, 0x40, 0xa6, 0x23, 0x46, 0x63, 0x47, 0x2e, 0x4a, 0x42, - 0x39, 0xc2, 0x0b, 0x11, 0x4a, 0x96, 0x2d, 0x47, 0xac, 0xde, 0x03, 0x4c, 0x9d, 0x63, 0x4c, 0x89, - 0x7d, 0xa4, 0x06, 0xa0, 0x47, 0x58, 0x0c, 0xe5, 0x7a, 0x5c, 0x02, 0xba, 0xef, 0xd2, 0xce, 0x10, - 0x74, 0x5a, 0x41, 0x43, 0xb9, 0x86, 0x2e, 0xff, 0xcb, 0x2c, 0x28, 0x8d, 0xce, 0x0b, 0xfc, 0x11, - 0x98, 0x72, 0x1d, 0x26, 0xe7, 0x21, 0xb7, 0xfe, 0xdd, 0xd1, 0x05, 0xf7, 0x82, 0x69, 0x4c, 0xd4, - 0x47, 0x82, 0x01, 0x3e, 0x01, 0x45, 0x6d, 0x18, 0xf9, 0x91, 0x96, 0xab, 0x78, 0x71, 0x42, 0xee, - 0xd1, 0x74, 0x75, 0x38, 0xe8, 0x57, 0x0a, 0xdb, 0x3e, 0xc2, 0x4f, 0x6a, 0x3b, 0x5a, 0x86, 0x0a, - 0x1a, 0x1a, 0x7a, 0x88, 0xc1, 0x7c, 0x48, 0x1c, 0x1c, 0x9c, 0x0c, 0xcd, 0xc7, 0x04, 0xf2, 0xdd, - 0xf7, 0x3f, 0x0e, 0xc9, 0x2f, 0x0f, 0xfa, 0x95, 0xb2, 0x26, 0x8f, 0xc5, 0xa8, 0xac, 0xd1, 0xbb, - 0x07, 0x27, 0xe1, 0x27, 0xee, 0x82, 0x72, 0xb4, 0xf3, 0xed, 0xa0, 0x8d, 0x3d, 0x11, 0x49, 0x39, - 0x8b, 0xea, 0xb4, 0x8f, 0x76, 0xff, 0x6e, 0x1b, 0x7b, 0x5b, 0x0d, 0x54, 0xdc, 0x1f, 0x12, 0x88, - 0xe5, 0x39, 0x13, 0x1c, 0xf8, 0xdc, 0x67, 0xe6, 0x25, 0xb9, 0xde, 0xf5, 0x1b, 0x5c, 0x01, 0x25, - 0xd6, 0x0d, 0x02, 0x9f, 0x72, 0x66, 0x37, 0xdb, 0x98, 0x31, 0x7b, 0x4f, 0x56, 0x02, 0x19, 0x54, - 0x08, 0xe5, 0x1b, 0x42, 0x5c, 0x9f, 0x80, 0x6c, 0xca, 0x02, 0x60, 0x14, 0xb9, 0x01, 0x3b, 0xe0, - 0x8a, 0x43, 0xf6, 0x71, 0xb7, 0xcd, 0xed, 0x0e, 0x6e, 0xda, 0x41, 0x94, 0xc6, 0x75, 0xb1, 0xf7, - 0xea, 0x0b, 0x73, 0x7d, 0xdd, 0x1c, 0xf4, 0x2b, 0x0b, 0x0d, 0x45, 0x30, 0xa4, 0x41, 0x0b, 0x9a, - 0xf6, 0x3e, 0x6e, 0x26, 0x4a, 0xbe, 0x6b, 0x20, 0x2f, 0xf2, 0x5d, 0x9c, 0x19, 0xb3, 0xea, 0xdc, - 0xed, 0xb8, 0x71, 0xea, 0x95, 0x20, 0xdc, 0x4b, 0x80, 0x80, 0x06, 0xe1, 0x5e, 0x0c, 0x5a, 0x02, - 0x73, 0x94, 0x30, 0xc2, 0x99, 0x2a, 0x63, 0x65, 0x21, 0x90, 0x41, 0x40, 0xc9, 0x44, 0xfd, 0x0a, - 0x7f, 0x00, 0xca, 0x5d, 0x46, 0x98, 0x7d, 0x7b, 0xdd, 0xde, 0x73, 0x75, 0xa5, 0x2d, 0xcf, 0xf9, - 0x4c, 0xbd, 0x3c, 0xe8, 0x57, 0xf2, 0x8f, 0x19, 0x61, 0xb7, 0xd7, 0xeb, 0xae, 0xac, 0xb7, 0x51, - 0xbe, 0x9b, 0x7c, 0x15, 0x3e, 0x44, 0x33, 0x28, 0x4e, 0x58, 0x79, 0xe2, 0x67, 0xd0, 0x5c, 0x28, - 0xfc, 0xc0, 0x77, 0x3d, 0x78, 0x03, 0x40, 0xed, 0x83, 0x3c, 0xc9, 0x3d, 0xdf, 0x6b, 0x12, 0x26, - 0x8f, 0xef, 0x0c, 0x2a, 0x29, 0x8d, 0xc0, 0xed, 0x48, 0x39, 0x7c, 0x0a, 0x60, 0x38, 0xd5, 0xfb, - 0x3e, 0xed, 0x60, 0x2e, 0xa7, 0xb9, 0x28, 0xa7, 0x79, 0x65, 0x6c, 0x9a, 0x55, 0xc3, 0xb3, 0x8b, - 0x4f, 0xda, 0x3e, 0x76, 0xee, 0x45, 0xf8, 0xfa, 0xb4, 0xd8, 0x28, 0xa8, 0xac, 0x99, 0x62, 0x85, - 0xce, 0xc1, 0xff, 0x3c, 0x05, 0x72, 0xf7, 0x6b, 0x1b, 0x0f, 0x09, 0xe7, 0xa2, 0xa7, 0x81, 0xd7, - 0xc0, 0x6c, 0x97, 0x11, 0x1b, 0x3b, 0x54, 0xee, 0xca, 0x4c, 0x1d, 0x0c, 0xfa, 0x95, 0x99, 0xc7, - 0x8c, 0xd4, 0x1a, 0x08, 0xcd, 0x74, 0x19, 0xa9, 0x39, 0x14, 0xde, 0x00, 0xa2, 0x74, 0xb4, 0x3b, - 0x98, 0xb6, 0x5c, 0xb5, 0xd1, 0xf2, 0xf5, 0xfc, 0xa0, 0x5f, 0xc9, 0xd6, 0x1a, 0xe8, 0xbe, 0x14, - 0xa2, 0x2c, 0x76, 0xa8, 0x7a, 0x84, 0x1f, 0x82, 0xa2, 0x5e, 0x7d, 0xb2, 0x2e, 0xf2, 0xbb, 0x5c, - 0x37, 0x40, 0x2f, 0x8d, 0x35, 0x06, 0x0d, 0xdd, 0xbb, 0xaa, 0xed, 0xfd, 0x2b, 0xd1, 0x17, 0xe4, - 0xa5, 0x6d, 0xfd, 0x91, 0xb2, 0x8c, 0xc9, 0x9a, 0x11, 0xd9, 0xf4, 0x45, 0xc9, 0x36, 0x42, 0xb2, - 0x4f, 0xc0, 0x55, 0xc6, 0x31, 0xef, 0xb2, 0xf1, 0x82, 0xed, 0xd2, 0xf9, 0x49, 0x2f, 0x2b, 0x8e, - 0xd1, 0x8a, 0xed, 0x5d, 0x60, 0x6a, 0xf2, 0xf1, 0x8a, 0x4d, 0xf5, 0x5a, 0x57, 0x94, 0x7e, 0xb4, - 0x18, 0x5b, 0xfe, 0xcf, 0x2c, 0xc8, 0x88, 0x98, 0x70, 0xcc, 0x09, 0x44, 0x00, 0x36, 0xbb, 0x94, - 0x12, 0xc1, 0x10, 0x6f, 0x36, 0xe3, 0x3c, 0x9b, 0x4d, 0x87, 0x5e, 0x9b, 0x27, 0x76, 0x15, 0x12, - 0x2b, 0x8b, 0xb9, 0x94, 0x38, 0x49, 0xce, 0xf4, 0x05, 0x38, 0xb5, 0x79, 0x82, 0xf3, 0x5d, 0x30, - 0xa7, 0x2e, 0x4b, 0x54, 0x02, 0xd1, 0x19, 0xf2, 0xf2, 0x28, 0x9b, 0x4c, 0x23, 0x28, 0xa7, 0xa0, - 0xf2, 0x65, 0x52, 0xee, 0x9e, 0xfe, 0x3f, 0xc9, 0xdd, 0x4f, 0xc1, 0x62, 0xd4, 0xbc, 0xba, 0xb4, - 0x43, 0x1c, 0x3b, 0x2a, 0xb5, 0x30, 0xd7, 0x11, 0x7e, 0x51, 0x73, 0x3a, 0x2d, 0x1b, 0xd3, 0xab, - 0x61, 0x93, 0x2b, 0x29, 0x1a, 0x9a, 0xa1, 0xc6, 0xe1, 0x3b, 0xc0, 0x94, 0xf4, 0x0e, 0x39, 0xb2, - 0x75, 0xa4, 0xa3, 0xee, 0x5c, 0x05, 0x78, 0x5e, 0xe8, 0x1b, 0xe4, 0xe8, 0xa1, 0xd4, 0xea, 0x36, - 0x1d, 0x81, 0xcb, 0x71, 0xb1, 0x9a, 0x5c, 0x14, 0xb3, 0x72, 0xd0, 0xd6, 0xd8, 0x99, 0xa2, 0x2b, - 0x53, 0xb5, 0x42, 0xd0, 0x7c, 0x30, 0xf4, 0xae, 0xd6, 0x1a, 0x01, 0xaf, 0x04, 0xc4, 0x73, 0x04, - 0x2d, 0x0e, 0x82, 0xb6, 0xdb, 0x94, 0x6b, 0x34, 0x1a, 0xae, 0xce, 0xcd, 0xe3, 0xc5, 0x7c, 0x8c, - 0x0d, 0xc7, 0x85, 0x16, 0x35, 0xd1, 0x04, 0x1d, 0xdc, 0x04, 0xa5, 0x9f, 0x76, 0x49, 0x97, 0x38, - 0x36, 0x25, 0x2c, 0xf0, 0x3d, 0x46, 0x98, 0x99, 0x95, 0x25, 0xfe, 0xa4, 0x50, 0x6d, 0xf8, 0x9d, - 0x0e, 0xf6, 0x1c, 0x54, 0x54, 0x36, 0x28, 0x34, 0x11, 0x34, 0xa1, 0xb7, 0x32, 0x3d, 0x33, 0xce, - 0x4c, 0xf0, 0xd5, 0x34, 0xda, 0x06, 0x69, 0x13, 0xf8, 0x37, 0x00, 0x6a, 0x6f, 0x64, 0x36, 0xc5, - 0xcd, 0x26, 0x09, 0x54, 0x5e, 0x9f, 0x30, 0xd4, 0x70, 0x3f, 0x55, 0x45, 0x82, 0xad, 0x49, 0x28, - 0xd2, 0x83, 0x89, 0x25, 0xf0, 0x3e, 0x58, 0x08, 0x3d, 0x93, 0x9c, 0xda, 0x3d, 0x79, 0x0a, 0x4c, - 0xb8, 0xb0, 0x11, 0x96, 0xda, 0x1d, 0x04, 0xb5, 0x61, 0x42, 0x06, 0x6f, 0x8a, 0xa6, 0xd5, 0x3e, - 0x76, 0x3d, 0xc7, 0x3f, 0x66, 0x36, 0x3e, 0xc2, 0x6e, 0x5b, 0x94, 0xc2, 0xfa, 0x6c, 0x80, 0xb4, - 0xf7, 0x44, 0xa9, 0x6a, 0xa1, 0x66, 0xf1, 0x3f, 0x0c, 0x00, 0x12, 0xfe, 0x2c, 0x83, 0xd9, 0x40, - 0x65, 0x74, 0xb9, 0xe3, 0xe7, 0xea, 0x99, 0xc1, 0xb3, 0xca, 0x74, 0x90, 0xeb, 0xbd, 0x8a, 0x42, - 0x05, 0xfc, 0x01, 0x98, 0x0d, 0xdd, 0x4c, 0x7f, 0xa5, 0x9b, 0x7a, 0xff, 0x86, 0x16, 0xf0, 0x9d, - 0xf3, 0xdf, 0x48, 0x29, 0x4b, 0x09, 0xd7, 0x67, 0xc7, 0x3f, 0x99, 0x20, 0x1b, 0xd5, 0x68, 0xf0, - 0xbd, 0x64, 0x2d, 0x77, 0xfd, 0xcc, 0x5a, 0xee, 0x05, 0x45, 0xdc, 0x06, 0x00, 0x4d, 0x4a, 0xb0, - 0xbe, 0x3c, 0x4a, 0x5f, 0xe4, 0xf2, 0x48, 0xdb, 0xd5, 0xb8, 0x20, 0xe9, 0x06, 0x4e, 0x48, 0x32, - 0x75, 0x11, 0x12, 0x6d, 0x57, 0xe3, 0x51, 0x61, 0x3f, 0x9d, 0xe8, 0x37, 0x96, 0x40, 0xce, 0x21, - 0xac, 0x49, 0xdd, 0x40, 0xec, 0x09, 0x99, 0x3e, 0xb2, 0x28, 0x29, 0x82, 0x5b, 0x00, 0x60, 0xce, - 0xa9, 0xbb, 0xd7, 0xe5, 0x84, 0x99, 0x33, 0x72, 0x45, 0xbf, 0x79, 0xe6, 0x44, 0x54, 0x6b, 0x11, - 0x76, 0xd3, 0xe3, 0xf4, 0x04, 0x25, 0x8c, 0xe1, 0x4f, 0x40, 0x4e, 0xe7, 0x42, 0x5b, 0x4c, 0xea, - 0xec, 0xc5, 0x0b, 0x64, 0x79, 0xd9, 0x13, 0xca, 0x1b, 0x0c, 0x81, 0xa3, 0x10, 0xc3, 0x60, 0x1d, - 0x40, 0x46, 0xa8, 0x4c, 0xd6, 0x01, 0xf5, 0xf7, 0xdd, 0x36, 0x11, 0x25, 0x67, 0x46, 0x96, 0x9c, - 0xf2, 0x92, 0xea, 0xa1, 0xd2, 0xee, 0x2a, 0xe5, 0x56, 0x03, 0x95, 0xd8, 0xb0, 0xc4, 0x81, 0x6f, - 0x83, 0x2b, 0xfa, 0xfe, 0xd3, 0x16, 0x3a, 0x42, 0xe5, 0x7d, 0x29, 0x61, 0x4c, 0x96, 0x68, 0x59, - 0xb4, 0xa0, 0xb5, 0x0f, 0xa5, 0xb2, 0xa6, 0x74, 0xf0, 0x87, 0x60, 0x31, 0x99, 0xa0, 0x46, 0x2c, - 0x81, 0xb4, 0x34, 0x13, 0x88, 0x61, 0xeb, 0x2a, 0x98, 0x97, 0xdb, 0x72, 0xc4, 0x2c, 0x27, 0xcd, - 0xca, 0x42, 0x35, 0x8c, 0xbf, 0x07, 0xb2, 0x6d, 0x5f, 0x11, 0x31, 0x73, 0x4e, 0xc6, 0x63, 0xe5, - 0xec, 0x78, 0x6c, 0x87, 0x50, 0x15, 0x8e, 0xd8, 0x74, 0x62, 0x21, 0x9d, 0x3f, 0x77, 0x21, 0x5d, - 0x98, 0x58, 0x48, 0x4f, 0x38, 0xf5, 0x8a, 0xdf, 0x66, 0xc7, 0x52, 0xfa, 0xb6, 0x3b, 0x96, 0xf2, - 0x05, 0x3a, 0x96, 0xb3, 0xbb, 0x08, 0xf8, 0xff, 0xd2, 0x45, 0xcc, 0x9f, 0xa7, 0x8b, 0x58, 0x38, - 0x47, 0x17, 0x71, 0xf9, 0x7c, 0x5d, 0xc4, 0x95, 0xaf, 0xdb, 0x45, 0x5c, 0x3d, 0x77, 0x17, 0x61, - 0x9e, 0xd1, 0x45, 0xbc, 0x03, 0xb2, 0xd4, 0xf7, 0xb9, 0x2d, 0xd3, 0xfc, 0x4b, 0x72, 0x76, 0xcd, - 0xb1, 0x9b, 0x42, 0xdf, 0xe7, 0x22, 0xc7, 0xa3, 0x0c, 0xd5, 0x4f, 0xf0, 0x23, 0x30, 0xe3, 0x11, - 0x2e, 0xe2, 0xba, 0x28, 0x0f, 0x9e, 0xbb, 0x7f, 0xe8, 0x57, 0xd6, 0x2f, 0xf4, 0xeb, 0xc7, 0x0e, - 0xe1, 0x5b, 0x8d, 0x41, 0xbf, 0x72, 0x49, 0x3e, 0xa0, 0x4b, 0x1e, 0xe1, 0xf2, 0xb6, 0x62, 0x4e, - 0x44, 0x9c, 0xe9, 0x7e, 0xc3, 0x7c, 0x79, 0xf2, 0xc1, 0x93, 0x68, 0x49, 0xd4, 0x75, 0x72, 0x42, - 0x80, 0x72, 0x1d, 0xdc, 0x8c, 0x1a, 0x96, 0x0d, 0x90, 0x95, 0x84, 0xe2, 0x70, 0x37, 0x5f, 0x99, - 0x3c, 0xbe, 0xf0, 0xf0, 0xaf, 0xcf, 0x0d, 0xfa, 0x95, 0xa8, 0xb4, 0x46, 0x19, 0xc1, 0x23, 0x8b, - 0xec, 0x5b, 0x60, 0x96, 0xa9, 0xa3, 0xce, 0x7c, 0x55, 0x52, 0x5c, 0x3d, 0xe3, 0x24, 0x44, 0x21, - 0x0e, 0xbe, 0x07, 0xc2, 0x82, 0xc4, 0x0e, 0x4d, 0xad, 0x17, 0x9b, 0x16, 0x34, 0x3e, 0xfc, 0x99, - 0xe9, 0x3a, 0x28, 0x44, 0xf5, 0xa3, 0x0c, 0xa2, 0x59, 0x91, 0x55, 0xe3, 0x9c, 0xae, 0x1a, 0x65, - 0x00, 0xe1, 0x1b, 0xa0, 0xd8, 0x65, 0xc4, 0x89, 0x51, 0xcc, 0x5c, 0x5a, 0x9a, 0x5a, 0xc9, 0xcb, - 0xa5, 0xe3, 0x84, 0x30, 0x26, 0x70, 0x92, 0x2d, 0x5e, 0x13, 0xe6, 0x6b, 0xf1, 0x2f, 0x3a, 0xd1, - 0x82, 0x80, 0xdf, 0xd3, 0x38, 0xfa, 0x99, 0xee, 0x4b, 0x6e, 0x9a, 0xcb, 0xb2, 0x81, 0x2b, 0x0d, - 0xfa, 0x95, 0xb9, 0x6d, 0xcc, 0x38, 0xfa, 0x40, 0x76, 0x24, 0x37, 0x95, 0x23, 0xe8, 0x33, 0xf5, - 0x36, 0x6e, 0x78, 0xcb, 0xbc, 0x36, 0xd1, 0xf0, 0xd6, 0x90, 0xe1, 0x2d, 0xf8, 0x29, 0x78, 0x79, - 0xb4, 0x4e, 0xa6, 0xa4, 0x49, 0xdc, 0x23, 0x75, 0x44, 0x5f, 0xbf, 0x48, 0x1d, 0x1e, 0x15, 0xd3, - 0x48, 0x33, 0xd4, 0xc4, 0x8e, 0xcb, 0xa9, 0xdf, 0x49, 0xd4, 0x1a, 0x78, 0xfd, 0x8c, 0x44, 0x27, - 0x20, 0x2a, 0xee, 0x20, 0x88, 0x9e, 0xe1, 0x2a, 0x80, 0x7b, 0xb2, 0x21, 0x3e, 0x11, 0xb5, 0x78, - 0x93, 0x78, 0x1c, 0xb7, 0x88, 0xf9, 0xc6, 0x92, 0xb1, 0x92, 0x46, 0x65, 0xad, 0xd9, 0x8d, 0x14, - 0xf0, 0x3b, 0xa0, 0x18, 0xf5, 0x10, 0xba, 0xfd, 0xfd, 0xce, 0x92, 0xb1, 0x72, 0x09, 0x15, 0x42, - 0xb1, 0x6e, 0x7a, 0xb1, 0xd8, 0xa4, 0xc2, 0x4a, 0xb4, 0xd2, 0xfa, 0x42, 0x94, 0x99, 0x2b, 0xf2, - 0x0c, 0x1a, 0xcb, 0x6e, 0xea, 0x6e, 0x54, 0xb7, 0xf0, 0xea, 0x04, 0x46, 0xd2, 0xb8, 0xd6, 0x40, - 0x4a, 0xc7, 0xc4, 0xce, 0x96, 0x12, 0x87, 0x6a, 0x09, 0x6c, 0x80, 0x82, 0xfe, 0x44, 0x48, 0xff, - 0xe6, 0x39, 0xe8, 0x51, 0x5e, 0x19, 0x85, 0x2c, 0x1f, 0x00, 0xcd, 0x1c, 0x75, 0x0b, 0xcc, 0x7c, - 0x4b, 0xf2, 0x54, 0xc6, 0x2e, 0x80, 0xc3, 0x21, 0x6a, 0xa6, 0xa2, 0x32, 0x0c, 0xc5, 0x4c, 0xb4, - 0x21, 0xba, 0x22, 0x9f, 0xd4, 0x85, 0x30, 0xf3, 0xbb, 0x92, 0xf7, 0x7c, 0x6d, 0x88, 0x22, 0x9a, - 0xa0, 0x62, 0xf0, 0x7d, 0x00, 0x12, 0x17, 0x22, 0x37, 0x2e, 0x76, 0x21, 0x82, 0x12, 0xb6, 0x10, - 0x83, 0x42, 0x40, 0xfd, 0x23, 0x57, 0xec, 0x47, 0x42, 0x45, 0xb6, 0x5b, 0x95, 0xa7, 0xd8, 0x1d, - 0x91, 0xa9, 0x77, 0x63, 0xcd, 0x45, 0xee, 0x51, 0xf3, 0x09, 0xc6, 0x2d, 0x07, 0x36, 0x40, 0x39, - 0x12, 0x88, 0x64, 0xe1, 0x60, 0x8e, 0xcd, 0xaa, 0xce, 0x14, 0xa3, 0x6b, 0xfe, 0xa1, 0xfc, 0xe5, - 0x1d, 0x95, 0x92, 0x16, 0x0d, 0xcc, 0xf1, 0xe2, 0x5f, 0x83, 0xe2, 0x48, 0xb9, 0x08, 0x4b, 0x60, - 0xea, 0x90, 0xa8, 0xdf, 0x15, 0xb2, 0x48, 0x3c, 0xc2, 0x05, 0x70, 0xe9, 0x08, 0xb7, 0xbb, 0xe1, - 0x35, 0xb9, 0x7a, 0xb9, 0x93, 0x7e, 0xd7, 0x58, 0xfc, 0x08, 0x14, 0x86, 0xab, 0x9b, 0x09, 0xd6, - 0xd5, 0xa4, 0xf5, 0x84, 0x24, 0x1a, 0x12, 0x24, 0x78, 0x75, 0x1f, 0xf0, 0x3e, 0x00, 0x51, 0x15, - 0xc5, 0xe0, 0x1d, 0x90, 0x8b, 0xff, 0x73, 0x42, 0xf4, 0x03, 0x53, 0xf2, 0x22, 0xe5, 0xac, 0xb2, - 0x0b, 0x01, 0x12, 0xd9, 0x2e, 0xff, 0x04, 0x5c, 0xd9, 0x90, 0x95, 0x7c, 0xac, 0xd6, 0x8d, 0x4a, - 0x1d, 0x80, 0x98, 0x55, 0x37, 0x19, 0x67, 0x93, 0x26, 0x3a, 0x8b, 0x6c, 0x44, 0xbf, 0xfc, 0x6f, - 0x06, 0xb8, 0xf2, 0x58, 0xd6, 0xf8, 0xdf, 0x06, 0x3d, 0xbc, 0x0b, 0x40, 0xfc, 0xbf, 0x15, 0x67, - 0xb6, 0x2f, 0xf7, 0x04, 0xe4, 0x3e, 0x66, 0x87, 0xba, 0xa1, 0xca, 0xee, 0x87, 0x82, 0xe5, 0xff, - 0x36, 0xc0, 0xfc, 0x8f, 0x08, 0x1f, 0x73, 0xee, 0x11, 0x28, 0xc4, 0xce, 0xd9, 0x5f, 0xbf, 0xc9, - 0x9a, 0x23, 0xb1, 0x9e, 0x7d, 0x73, 0x77, 0xff, 0xc7, 0x00, 0x97, 0xb7, 0x5d, 0x16, 0xfb, 0xcb, - 0x42, 0x87, 0x3f, 0x06, 0xc5, 0x64, 0x02, 0x88, 0x3d, 0x7e, 0xe3, 0x05, 0x5b, 0x7f, 0xb2, 0xcf, - 0x05, 0x9c, 0x44, 0x7c, 0x73, 0xaf, 0xc5, 0x26, 0xf1, 0xa9, 0x43, 0xa8, 0xfe, 0x49, 0x43, 0xbd, - 0xc8, 0x5f, 0x8c, 0xe4, 0xcf, 0xde, 0xea, 0xdf, 0x2a, 0xd4, 0x8b, 0x68, 0x03, 0x03, 0x71, 0x1c, - 0xa8, 0x7f, 0xa2, 0x90, 0xcf, 0xcb, 0xbf, 0x30, 0xc0, 0xfc, 0xc3, 0x09, 0x41, 0xfa, 0x1e, 0x98, - 0x39, 0xef, 0xea, 0x51, 0x3e, 0x69, 0xf8, 0x37, 0x1e, 0xd1, 0x5b, 0xf7, 0x00, 0x88, 0x0f, 0x37, - 0x58, 0x06, 0xf9, 0xdd, 0x07, 0x4f, 0x36, 0x91, 0xfd, 0x78, 0xe7, 0xc3, 0x9d, 0x07, 0x4f, 0x76, - 0x4a, 0xa9, 0x58, 0x54, 0xaf, 0x3d, 0x7a, 0xb4, 0x89, 0x3e, 0x2e, 0x19, 0x10, 0x82, 0x82, 0x12, - 0x6d, 0xfe, 0xed, 0xa3, 0x4d, 0xb4, 0x53, 0xdb, 0x2e, 0xa5, 0xeb, 0xff, 0x6e, 0x7c, 0xf1, 0xdc, - 0x32, 0xbe, 0x7c, 0x6e, 0x19, 0xbf, 0x7f, 0x6e, 0xa5, 0xfe, 0xf8, 0xdc, 0x4a, 0xfd, 0xe9, 0xb9, - 0x95, 0xfa, 0xf3, 0x73, 0x2b, 0xf5, 0x97, 0xe7, 0x96, 0xf1, 0xb3, 0x81, 0x65, 0xfc, 0x7c, 0x60, - 0xa5, 0x7e, 0x33, 0xb0, 0x8c, 0xdf, 0x0e, 0xac, 0xd4, 0xe7, 0x03, 0x2b, 0xf5, 0xbb, 0x81, 0x95, - 0xfa, 0x62, 0x60, 0x19, 0x5f, 0x0e, 0x2c, 0xe3, 0xf7, 0x03, 0x2b, 0xf5, 0xc7, 0x81, 0x65, 0xfc, - 0x69, 0x60, 0xa5, 0xfe, 0x3c, 0xb0, 0x8c, 0xbf, 0x0c, 0xac, 0xd4, 0xcf, 0x4e, 0xad, 0xd4, 0xcf, - 0x4f, 0x2d, 0xe3, 0x97, 0xa7, 0x56, 0xea, 0x57, 0xa7, 0x96, 0xf1, 0xeb, 0x53, 0x2b, 0xf5, 0x9b, - 0x53, 0x2b, 0xf5, 0xdb, 0x53, 0xcb, 0xf8, 0xfc, 0xd4, 0x32, 0x7e, 0x77, 0x6a, 0x19, 0x3f, 0xbe, - 0x71, 0xde, 0xaa, 0x92, 0x7b, 0xc1, 0xde, 0xde, 0x8c, 0x9c, 0x91, 0xdb, 0xff, 0x1b, 0x00, 0x00, - 0xff, 0xff, 0x1f, 0x91, 0x75, 0x03, 0xb0, 0x25, 0x00, 0x00, + golang_proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_cd134bac00aa082e) +} + +var fileDescriptor_end_device_cd134bac00aa082e = []byte{ + // 3529 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5a, 0x4b, 0x70, 0x1b, 0xc7, + 0x99, 0xc6, 0x80, 0x14, 0x09, 0x34, 0xde, 0x4d, 0x4a, 0x1a, 0xd3, 0x32, 0x40, 0x53, 0xb2, 0x43, + 0x3b, 0x22, 0x28, 0x51, 0x72, 0xe2, 0x28, 0x49, 0xc9, 0x00, 0x41, 0xc5, 0xb4, 0x29, 0x8a, 0xdb, + 0x92, 0xac, 0x75, 0x1c, 0x79, 0xaa, 0x89, 0x69, 0x82, 0x63, 0x02, 0x33, 0x93, 0xee, 0x06, 0x09, + 0xee, 0xa3, 0x2a, 0x87, 0xdd, 0xaa, 0xdc, 0x92, 0xc3, 0x6e, 0x55, 0x2e, 0x5b, 0x95, 0xda, 0xda, + 0xad, 0x4a, 0x6d, 0xed, 0x21, 0x47, 0x1f, 0x73, 0xf4, 0xd1, 0xc7, 0x54, 0x0e, 0x70, 0x04, 0x5e, + 0x72, 0x4c, 0xd5, 0x5e, 0x7c, 0xdc, 0xea, 0xc7, 0x3c, 0xf0, 0x20, 0x4d, 0xda, 0xeb, 0xbd, 0xb0, + 0x66, 0xfe, 0xff, 0xfb, 0xbf, 0xf9, 0xfb, 0xf5, 0x3f, 0x1a, 0x04, 0x4b, 0x6d, 0x8f, 0xe2, 0x23, + 0xec, 0xae, 0x30, 0x8e, 0x9b, 0x07, 0xab, 0xd8, 0x77, 0x56, 0x89, 0x6b, 0x5b, 0x36, 0x39, 0x74, + 0x9a, 0xa4, 0xea, 0x53, 0x8f, 0x7b, 0x30, 0xcf, 0xb9, 0x5b, 0xd5, 0xb8, 0xea, 0xe1, 0x9d, 0x85, + 0x95, 0x96, 0xc3, 0xf7, 0xbb, 0xbb, 0xd5, 0xa6, 0xd7, 0x59, 0x6d, 0x79, 0x2d, 0x6f, 0x55, 0xc2, + 0x76, 0xbb, 0x7b, 0xf2, 0x4d, 0xbe, 0xc8, 0x27, 0x65, 0xbe, 0xf0, 0xbd, 0x18, 0xbc, 0x73, 0xe4, + 0xf0, 0x03, 0xef, 0x68, 0xb5, 0xe5, 0xad, 0x48, 0xe5, 0xca, 0x21, 0x6e, 0x3b, 0x36, 0xe6, 0x1e, + 0x65, 0xab, 0xe1, 0xa3, 0xb6, 0xbb, 0xd6, 0xf2, 0xbc, 0x56, 0x9b, 0x48, 0x9f, 0xb0, 0xeb, 0x7a, + 0x1c, 0x73, 0xc7, 0x73, 0x99, 0xd6, 0x96, 0xb5, 0x36, 0xfc, 0xb6, 0xdd, 0xa5, 0x12, 0xa0, 0xf5, + 0x8b, 0xa3, 0xfa, 0x3d, 0x87, 0xb4, 0x6d, 0xab, 0x83, 0xd9, 0xc1, 0x08, 0x7f, 0x88, 0x60, 0x9c, + 0x76, 0x9b, 0x5c, 0x6b, 0x2b, 0xa3, 0x5a, 0xee, 0x74, 0x08, 0xe3, 0xb8, 0xe3, 0x9f, 0xe6, 0xc0, + 0x11, 0xc5, 0xbe, 0x4f, 0x68, 0xe0, 0xe0, 0xf5, 0xf1, 0x99, 0x75, 0x6c, 0xe2, 0x72, 0x67, 0xcf, + 0x89, 0x40, 0xd7, 0xc6, 0x41, 0x9f, 0x78, 0x8e, 0x7b, 0xba, 0xf6, 0x80, 0x1c, 0x07, 0xb6, 0x95, + 0x71, 0x6d, 0xb0, 0x48, 0x7a, 0x0a, 0xc6, 0x01, 0x1d, 0xc2, 0x18, 0x6e, 0x11, 0x76, 0x16, 0x82, + 0x63, 0x1b, 0x73, 0xac, 0x10, 0x4b, 0xbf, 0x9a, 0x02, 0xb3, 0x8f, 0x09, 0x63, 0x8e, 0xe7, 0xc2, + 0x67, 0x20, 0x65, 0x93, 0x43, 0x0b, 0xdb, 0x36, 0x35, 0x93, 0x8b, 0xc6, 0x72, 0xb6, 0xfe, 0xa3, + 0xcf, 0xfa, 0x95, 0xc4, 0x9f, 0xfa, 0x95, 0xbb, 0x2d, 0xaf, 0xca, 0xf7, 0x09, 0xdf, 0x77, 0xdc, + 0x16, 0xab, 0xba, 0x84, 0x1f, 0x79, 0xf4, 0x60, 0x75, 0x98, 0xdc, 0x3f, 0x68, 0xad, 0xf2, 0x63, + 0x9f, 0xb0, 0x6a, 0x83, 0x1c, 0xd6, 0x6c, 0x9b, 0xa2, 0x59, 0x5b, 0x3d, 0xc0, 0x1f, 0x80, 0x69, + 0x31, 0x2e, 0x73, 0x6a, 0xd1, 0x58, 0xce, 0xac, 0xbd, 0x5c, 0x1d, 0xde, 0x6f, 0x55, 0xfd, 0xfd, + 0xf7, 0xc9, 0x31, 0xab, 0xa7, 0xc4, 0x17, 0x3f, 0xef, 0x57, 0x0c, 0x24, 0x4d, 0xe0, 0xab, 0x20, + 0xd7, 0xc6, 0x8c, 0x5b, 0x7b, 0x56, 0xd3, 0xe5, 0x56, 0xd7, 0x37, 0xa7, 0x17, 0x8d, 0xe5, 0x1c, + 0x02, 0x42, 0xf8, 0x60, 0xdd, 0xe5, 0x4f, 0x7d, 0xb8, 0x0c, 0x4a, 0x12, 0xe2, 0x6a, 0x90, 0xed, + 0x1d, 0xb9, 0xe6, 0x25, 0x09, 0x93, 0xb6, 0xdb, 0x02, 0xd7, 0xf0, 0x8e, 0xdc, 0x10, 0x89, 0xe3, + 0xc8, 0x99, 0x08, 0x59, 0x0b, 0x91, 0x55, 0x30, 0x2f, 0x91, 0x4d, 0xcf, 0xdd, 0x8b, 0x83, 0x67, + 0x25, 0xb8, 0x28, 0x74, 0xeb, 0x9e, 0xbb, 0x17, 0xe2, 0xd7, 0x01, 0x60, 0x1c, 0x53, 0x4e, 0x6c, + 0x0b, 0x73, 0x33, 0x25, 0xc7, 0xb9, 0x50, 0x55, 0x3b, 0xa8, 0x1a, 0xec, 0xa0, 0xea, 0x93, 0x60, + 0x8b, 0xa9, 0x61, 0xfe, 0xfa, 0x8b, 0x8a, 0x81, 0xd2, 0xda, 0xae, 0xc6, 0xdf, 0x9b, 0x4e, 0x19, + 0xc5, 0xe4, 0xd2, 0x17, 0x19, 0x90, 0x7b, 0x58, 0x5b, 0xdf, 0xc1, 0x14, 0x77, 0x08, 0x27, 0x94, + 0xc1, 0xd7, 0x41, 0xaa, 0x83, 0x7b, 0x16, 0x71, 0xa8, 0x6f, 0x1a, 0x8b, 0xc6, 0x72, 0xb2, 0x9e, + 0x19, 0xf4, 0x2b, 0xb3, 0x0f, 0x71, 0x6f, 0x63, 0x13, 0xed, 0xa0, 0xd9, 0x0e, 0xee, 0x6d, 0x38, + 0xd4, 0x87, 0x6f, 0x82, 0x52, 0xd7, 0x6f, 0x3b, 0xee, 0x81, 0x65, 0x1f, 0x91, 0x76, 0xdb, 0x12, + 0x3b, 0x5a, 0x2e, 0x64, 0x0a, 0x15, 0x94, 0xa2, 0x21, 0xe4, 0xc2, 0x0b, 0x58, 0x05, 0x73, 0x62, + 0x40, 0xa3, 0xe8, 0x29, 0x89, 0x2e, 0x05, 0xaa, 0x08, 0xbf, 0x0b, 0xe6, 0xb0, 0x4d, 0x2d, 0xb1, + 0x73, 0x2c, 0x8a, 0x39, 0xb1, 0x1c, 0xd7, 0x26, 0x3d, 0xb9, 0x1a, 0xf9, 0xb5, 0x57, 0x46, 0x57, + 0xb4, 0x81, 0x39, 0x46, 0x98, 0x93, 0x4d, 0x01, 0xaa, 0xcf, 0x0f, 0xfa, 0x95, 0x62, 0xad, 0x81, + 0x86, 0xa4, 0xa8, 0x88, 0x6d, 0x3a, 0x24, 0x81, 0xef, 0x00, 0x28, 0xbe, 0xc1, 0x7b, 0x96, 0xef, + 0x1d, 0x11, 0xaa, 0x3f, 0x21, 0x57, 0xb2, 0x3e, 0x37, 0xe8, 0x57, 0x0a, 0xb5, 0x06, 0x7a, 0xd2, + 0xdb, 0x11, 0x3a, 0x45, 0x51, 0xc0, 0x36, 0x8d, 0x0b, 0xe0, 0x2d, 0x90, 0x15, 0x0c, 0xee, 0xae, + 0xc5, 0x29, 0x76, 0x99, 0x5a, 0xdb, 0x7a, 0x7e, 0xd0, 0xaf, 0x80, 0x5a, 0x03, 0x6d, 0xef, 0x3e, + 0x11, 0x52, 0x04, 0xb0, 0x4d, 0xf5, 0x33, 0xbc, 0x03, 0x72, 0xc2, 0x02, 0x37, 0x0f, 0xac, 0xb6, + 0xd3, 0x71, 0xb8, 0x5a, 0xe1, 0x7a, 0x61, 0xd0, 0xaf, 0x64, 0x6a, 0x0d, 0x54, 0x6b, 0x1e, 0x6c, + 0x09, 0x31, 0xca, 0x60, 0x9b, 0x06, 0x2f, 0x71, 0x23, 0x9b, 0xb4, 0xf1, 0xb1, 0x5c, 0xf0, 0x21, + 0xa3, 0x86, 0x10, 0x07, 0x46, 0xf2, 0x05, 0xde, 0x05, 0x69, 0xda, 0xbb, 0xad, 0x0d, 0xd2, 0x72, + 0xde, 0xae, 0x8e, 0xce, 0x1b, 0xea, 0x29, 0xc3, 0x14, 0xed, 0xdd, 0x56, 0x56, 0xab, 0x60, 0x5e, + 0x5a, 0x85, 0xf3, 0xee, 0xed, 0xed, 0x31, 0xc2, 0x4d, 0x20, 0x37, 0x62, 0x49, 0xe0, 0xf4, 0x1c, + 0x3e, 0x92, 0x0a, 0xb8, 0x05, 0xe6, 0x68, 0x6f, 0x6d, 0x6c, 0xa1, 0x32, 0xe7, 0x58, 0x28, 0x54, + 0xa4, 0xbd, 0xb5, 0xe1, 0x25, 0xb9, 0x0e, 0x72, 0x82, 0x6d, 0x8f, 0x92, 0x9f, 0x77, 0x89, 0xdb, + 0x3c, 0x36, 0xb3, 0x8b, 0xc6, 0xf2, 0x34, 0xca, 0xd2, 0xde, 0xda, 0x83, 0x40, 0x06, 0x7f, 0x0a, + 0xae, 0x52, 0x22, 0xc2, 0x9a, 0xdc, 0x43, 0x96, 0x4f, 0xa8, 0xe3, 0xd9, 0x4e, 0xd3, 0xe1, 0xc7, + 0x66, 0x4e, 0x7e, 0x76, 0x69, 0x6c, 0x9c, 0x12, 0x2e, 0x36, 0xd6, 0x46, 0xcf, 0xf7, 0x5c, 0xe2, + 0x72, 0x74, 0x99, 0x86, 0xb2, 0x9d, 0x88, 0x00, 0x3e, 0x07, 0xa6, 0xe6, 0x6e, 0x7a, 0x5d, 0x97, + 0x0f, 0x91, 0xe7, 0x25, 0xf9, 0xf5, 0xc9, 0xe4, 0xeb, 0x02, 0x1e, 0xb2, 0x5f, 0xa1, 0x91, 0x30, + 0x4e, 0xbf, 0x09, 0xf2, 0xe2, 0x68, 0xd9, 0x5d, 0x7e, 0x6c, 0x35, 0x8f, 0x9b, 0x6d, 0x62, 0x16, + 0x26, 0x93, 0xd6, 0x5a, 0x2d, 0x4a, 0x5a, 0x98, 0x13, 0xbb, 0xd1, 0xe5, 0xc7, 0xeb, 0x02, 0x8a, + 0xb2, 0x1d, 0xdc, 0x0b, 0xdf, 0x60, 0x0d, 0xa4, 0x9a, 0xfb, 0xd8, 0x75, 0x49, 0x9b, 0x99, 0xc5, + 0xc5, 0xa9, 0xe5, 0xcc, 0xda, 0x6b, 0xa3, 0x24, 0x43, 0xc7, 0xba, 0xba, 0xae, 0xd0, 0x28, 0x34, + 0x13, 0x87, 0xd2, 0x77, 0xdc, 0x96, 0xc5, 0xda, 0x1e, 0x8f, 0xcd, 0x79, 0x49, 0xce, 0x79, 0x49, + 0xa8, 0x1e, 0xb7, 0x3d, 0x1e, 0x4d, 0xfc, 0x33, 0xf0, 0x52, 0x84, 0x1f, 0x5d, 0x71, 0x78, 0x9e, + 0x15, 0xbf, 0x1c, 0x90, 0x0e, 0x2f, 0xfb, 0x1b, 0xa0, 0xb8, 0x4b, 0x70, 0xd3, 0x73, 0x63, 0x5e, + 0xcc, 0x49, 0x2f, 0x0a, 0x4a, 0x1e, 0xfa, 0xb0, 0xf0, 0x5f, 0x49, 0x30, 0xab, 0x47, 0x22, 0xcc, + 0x74, 0x00, 0x8a, 0xcc, 0x0c, 0x65, 0xa6, 0xe4, 0x91, 0xeb, 0x2b, 0x00, 0x86, 0xf1, 0x27, 0x02, + 0x27, 0xd5, 0x48, 0x03, 0x4d, 0x04, 0xdf, 0x02, 0x73, 0x1d, 0xc7, 0x1d, 0x1b, 0xe3, 0xd4, 0xb9, + 0x76, 0x75, 0xc7, 0x71, 0x87, 0x87, 0x27, 0xd8, 0xc4, 0xaa, 0x7f, 0x8d, 0x60, 0x86, 0x8a, 0x62, + 0xd1, 0x47, 0xcf, 0x08, 0x71, 0xf1, 0x6e, 0x9b, 0x58, 0x6a, 0x90, 0x32, 0x62, 0xa5, 0x50, 0x56, + 0x09, 0x9f, 0x4a, 0xd9, 0xbd, 0xe9, 0x4f, 0x7f, 0x5b, 0x49, 0xa8, 0xbf, 0x4b, 0x1d, 0x90, 0xdf, + 0x70, 0xed, 0x86, 0x2c, 0xc1, 0xea, 0x14, 0xbb, 0x36, 0xbc, 0x02, 0x92, 0x8e, 0x2d, 0xa7, 0x2a, + 0x5d, 0x9f, 0x19, 0xf4, 0x2b, 0xc9, 0xcd, 0x06, 0x4a, 0x3a, 0x36, 0x84, 0x60, 0xda, 0xc5, 0x3a, + 0x88, 0xa7, 0x91, 0x7c, 0x86, 0x2f, 0x81, 0xa9, 0x2e, 0x6d, 0xcb, 0xa1, 0xa7, 0xeb, 0xb3, 0x83, + 0x7e, 0x65, 0xea, 0x29, 0xda, 0x42, 0x42, 0x06, 0xe7, 0xc1, 0xa5, 0xb6, 0xd7, 0xf2, 0x98, 0x39, + 0xbd, 0x38, 0xb5, 0x9c, 0x46, 0xea, 0x65, 0xc9, 0x8e, 0x7d, 0xee, 0xa1, 0x67, 0x93, 0xb6, 0x48, + 0x28, 0xbb, 0xe2, 0xbb, 0x56, 0xf8, 0x51, 0x99, 0x50, 0xa4, 0x2f, 0x9b, 0x0d, 0x34, 0x2b, 0x95, + 0x9b, 0x81, 0x5b, 0xc9, 0x53, 0xdd, 0x9a, 0x8a, 0xdc, 0x5a, 0xfa, 0xd7, 0x24, 0x78, 0x39, 0xfc, + 0xcc, 0x07, 0x84, 0x8a, 0x8c, 0xbe, 0x19, 0xd5, 0x43, 0xf0, 0xd1, 0xd8, 0x37, 0xef, 0xc6, 0xbe, + 0x39, 0xf8, 0xa2, 0xf2, 0x1a, 0x78, 0xf5, 0xe3, 0x8f, 0xf0, 0xca, 0xdf, 0xdd, 0x5a, 0xf9, 0xc1, + 0xf3, 0xe5, 0xfb, 0xf7, 0x3e, 0x5a, 0x79, 0x7e, 0x3f, 0x78, 0x7d, 0xe3, 0xef, 0xd7, 0x6e, 0xfe, + 0xe3, 0x8d, 0x7f, 0xf8, 0xf8, 0x46, 0xef, 0xb5, 0xc8, 0xb9, 0x47, 0x20, 0xd5, 0x11, 0xa3, 0xb1, + 0x42, 0x17, 0x25, 0xa1, 0x1c, 0xe1, 0x85, 0x08, 0x25, 0xcb, 0xa6, 0x2d, 0x76, 0xef, 0x3e, 0xa6, + 0xf6, 0x11, 0xa6, 0xc4, 0x3a, 0x54, 0x03, 0xd0, 0x23, 0x2c, 0x04, 0x72, 0x3d, 0x2e, 0x01, 0xdd, + 0x73, 0x68, 0x67, 0x08, 0x3a, 0xad, 0xa0, 0x81, 0x5c, 0x43, 0x97, 0xfe, 0x65, 0x16, 0x14, 0x47, + 0xe7, 0x05, 0xfe, 0x04, 0x4c, 0x39, 0x36, 0x93, 0xf3, 0x90, 0x59, 0xfb, 0xee, 0xe8, 0x86, 0x3b, + 0x63, 0x1a, 0x63, 0xf5, 0x91, 0x60, 0x80, 0xcf, 0x40, 0x41, 0x1b, 0x86, 0x7e, 0x24, 0xe5, 0x2e, + 0x5e, 0x98, 0x10, 0x7b, 0x34, 0x5d, 0x1d, 0x0e, 0xfa, 0x95, 0xfc, 0x96, 0x87, 0xf0, 0xb3, 0xda, + 0xb6, 0x96, 0xa1, 0xbc, 0x86, 0x06, 0x1e, 0x62, 0x30, 0x17, 0x10, 0xfb, 0xfb, 0xc7, 0x43, 0xf3, + 0x31, 0x81, 0x7c, 0xe7, 0xdd, 0x0f, 0x03, 0xf2, 0xcb, 0x83, 0x7e, 0xa5, 0xa4, 0xc9, 0x23, 0x31, + 0x2a, 0x69, 0xf4, 0xce, 0xfe, 0x71, 0xf0, 0x89, 0xfb, 0xa0, 0x14, 0x9e, 0x7c, 0xcb, 0x6f, 0x63, + 0x57, 0xac, 0xa4, 0x9c, 0x45, 0x95, 0xed, 0xc3, 0xd3, 0xbf, 0xd3, 0xc6, 0xee, 0x66, 0x03, 0x15, + 0xf6, 0x86, 0x04, 0x62, 0x7b, 0xce, 0xf8, 0xfb, 0x1e, 0xf7, 0x98, 0x79, 0x49, 0xee, 0x77, 0xfd, + 0x06, 0x97, 0x41, 0x91, 0x75, 0x7d, 0xdf, 0xa3, 0x9c, 0x59, 0xcd, 0x36, 0x66, 0xcc, 0xda, 0x95, + 0x95, 0x40, 0x0a, 0xe5, 0x03, 0xf9, 0xba, 0x10, 0xd7, 0x27, 0x20, 0x9b, 0xb2, 0x00, 0x18, 0x45, + 0xae, 0xc3, 0x0e, 0xb8, 0x62, 0x93, 0x3d, 0xdc, 0x6d, 0x73, 0xab, 0x83, 0x9b, 0x96, 0x1f, 0x86, + 0x71, 0x5d, 0xec, 0xbd, 0x72, 0x66, 0xac, 0xaf, 0x9b, 0x83, 0x7e, 0x65, 0xbe, 0xa1, 0x08, 0x86, + 0x34, 0x68, 0x5e, 0xd3, 0x3e, 0xc4, 0xcd, 0x58, 0xc9, 0x77, 0x1d, 0xe4, 0x44, 0xbc, 0x8b, 0x22, + 0x63, 0x5a, 0xe5, 0xdd, 0x8e, 0x13, 0x85, 0x5e, 0x09, 0xc2, 0xbd, 0x18, 0x08, 0x68, 0x10, 0xee, + 0x45, 0xa0, 0x45, 0x90, 0xa5, 0x84, 0x11, 0xce, 0x54, 0x19, 0x2b, 0x0b, 0x81, 0x14, 0x02, 0x4a, + 0x26, 0xea, 0x57, 0xf8, 0x43, 0x50, 0xea, 0x32, 0xc2, 0xac, 0x3b, 0x6b, 0xd6, 0xae, 0xa3, 0x2b, + 0x6d, 0x99, 0xe7, 0x53, 0xf5, 0xd2, 0xa0, 0x5f, 0xc9, 0x3d, 0x65, 0x84, 0xdd, 0x59, 0xab, 0x3b, + 0xb2, 0xde, 0x46, 0xb9, 0x6e, 0xfc, 0x55, 0xf8, 0x10, 0xce, 0xa0, 0xc8, 0xb0, 0x32, 0xe3, 0xa7, + 0x50, 0x36, 0x10, 0xbe, 0xe7, 0x39, 0x2e, 0xbc, 0x09, 0xa0, 0xf6, 0x41, 0x66, 0x72, 0xd7, 0x73, + 0x9b, 0x84, 0xc9, 0xf4, 0x9d, 0x42, 0x45, 0xa5, 0x11, 0xb8, 0x6d, 0x29, 0x87, 0xcf, 0x01, 0x0c, + 0xa6, 0x7a, 0xcf, 0xa3, 0x1d, 0xcc, 0xe5, 0x34, 0x17, 0xe4, 0x34, 0x2f, 0x8f, 0x4d, 0xb3, 0x6a, + 0x78, 0x76, 0xf0, 0x71, 0xdb, 0xc3, 0xf6, 0x83, 0x10, 0x5f, 0x9f, 0x16, 0x07, 0x05, 0x95, 0x34, + 0x53, 0xa4, 0xd0, 0x31, 0xf8, 0x9f, 0x66, 0x40, 0xe6, 0x61, 0x6d, 0xfd, 0x31, 0xe1, 0x5c, 0xf4, + 0x34, 0xf0, 0x3a, 0x98, 0xed, 0x32, 0x62, 0x61, 0x9b, 0xca, 0x53, 0x99, 0xaa, 0x83, 0x41, 0xbf, + 0x32, 0xf3, 0x94, 0x91, 0x5a, 0x03, 0xa1, 0x99, 0x2e, 0x23, 0x35, 0x9b, 0xc2, 0x9b, 0x40, 0x94, + 0x8e, 0x56, 0x07, 0xd3, 0x96, 0xa3, 0x0e, 0x5a, 0xae, 0x9e, 0x1b, 0xf4, 0x2b, 0xe9, 0x5a, 0x03, + 0x3d, 0x94, 0x42, 0x94, 0xc6, 0x36, 0x55, 0x8f, 0xf0, 0x7d, 0x50, 0xd0, 0xbb, 0x4f, 0xd6, 0x45, + 0x5e, 0x97, 0xeb, 0x06, 0xe8, 0xa5, 0xb1, 0xc6, 0xa0, 0xa1, 0x7b, 0x5b, 0x75, 0xbc, 0x7f, 0x23, + 0xfa, 0x82, 0x9c, 0xb4, 0xad, 0x3f, 0x51, 0x96, 0x11, 0x59, 0x33, 0x24, 0x9b, 0xbe, 0x28, 0xd9, + 0x7a, 0x40, 0xf6, 0x11, 0xb8, 0xca, 0x38, 0xe6, 0x5d, 0x36, 0x5e, 0xb0, 0x5d, 0x3a, 0x3f, 0xe9, + 0x65, 0xc5, 0x31, 0x5a, 0xb1, 0xbd, 0x0d, 0x4c, 0x4d, 0x3e, 0x5e, 0xb1, 0xa9, 0x5e, 0xeb, 0x8a, + 0xd2, 0x8f, 0x15, 0x63, 0x1b, 0xf1, 0x0a, 0x79, 0xf6, 0x94, 0xf5, 0x8e, 0xd6, 0x2c, 0xa8, 0x96, + 0x3f, 0xc0, 0xed, 0x2e, 0x89, 0x95, 0xcc, 0xcf, 0x27, 0x57, 0xc0, 0xea, 0x9c, 0x56, 0xcf, 0x22, + 0x1c, 0xca, 0xeb, 0x8a, 0x76, 0xbc, 0x24, 0xae, 0x8d, 0x96, 0xc4, 0x69, 0x49, 0x7c, 0x6d, 0x6c, + 0xca, 0x9e, 0x6e, 0xba, 0xfc, 0x7b, 0x77, 0x15, 0xcd, 0x50, 0xc1, 0xbc, 0xf0, 0x63, 0x90, 0x8d, + 0xfb, 0x0e, 0x57, 0xc0, 0xa5, 0x43, 0xf1, 0x20, 0xb7, 0xde, 0x19, 0x6d, 0x81, 0x42, 0x2d, 0x6c, + 0x02, 0x38, 0xee, 0x29, 0xbc, 0x33, 0x4c, 0xf2, 0x15, 0x65, 0x8c, 0xc2, 0x2e, 0xfd, 0x67, 0x1a, + 0xa4, 0xc4, 0x0c, 0x70, 0xcc, 0x09, 0x44, 0x00, 0x36, 0xbb, 0x94, 0x12, 0xb1, 0x68, 0x51, 0x7c, + 0x33, 0xce, 0x13, 0xdf, 0xf4, 0x69, 0xd3, 0xe6, 0xb1, 0x40, 0x86, 0xc4, 0x61, 0x66, 0x0e, 0x25, + 0x76, 0x9c, 0x33, 0x79, 0x01, 0x4e, 0x6d, 0x1e, 0xe3, 0x7c, 0x1b, 0x64, 0xd5, 0xfd, 0x95, 0x8a, + 0xd9, 0x3a, 0x29, 0x5d, 0x1e, 0x65, 0x93, 0x91, 0x1b, 0x65, 0x14, 0x54, 0xbe, 0x4c, 0x4a, 0x97, + 0xd3, 0xff, 0x27, 0xe9, 0xf2, 0x39, 0x58, 0x08, 0xef, 0x0b, 0x1c, 0xda, 0x21, 0xb6, 0x15, 0x56, + 0xb7, 0x98, 0xeb, 0x43, 0x75, 0xd6, 0x7d, 0xc0, 0xb4, 0xbc, 0x0b, 0xb8, 0x1a, 0xdc, 0x2b, 0x48, + 0x8a, 0x86, 0x66, 0xa8, 0x71, 0xf8, 0x16, 0x30, 0x25, 0xbd, 0x4d, 0x0e, 0x2d, 0x7d, 0xb8, 0xc2, + 0x0b, 0x11, 0x75, 0xa6, 0xe6, 0x84, 0xbe, 0x41, 0x0e, 0x1f, 0x4b, 0xad, 0xbe, 0x19, 0x41, 0xe0, + 0x72, 0xd4, 0x1f, 0xc4, 0xcf, 0xe1, 0xac, 0x1c, 0x74, 0x79, 0x2c, 0x8d, 0xeb, 0x66, 0x40, 0x1d, + 0x4a, 0x34, 0xe7, 0x0f, 0xbd, 0xab, 0x43, 0x4a, 0xc0, 0x35, 0x9f, 0xb8, 0xb6, 0xa0, 0xc5, 0xbe, + 0xdf, 0x76, 0x9a, 0x32, 0x2c, 0x84, 0xc3, 0xd5, 0xc7, 0x6c, 0xbc, 0x7f, 0x8a, 0xb0, 0xc1, 0xb8, + 0xd0, 0x82, 0x26, 0x9a, 0xa0, 0x83, 0x1b, 0xa0, 0xf8, 0xf3, 0x2e, 0xe9, 0x12, 0xdb, 0xa2, 0x84, + 0xf9, 0x9e, 0xcb, 0x08, 0x33, 0xd3, 0xb2, 0xab, 0x9a, 0xb4, 0x54, 0xeb, 0x5e, 0xa7, 0x83, 0x5d, + 0x1b, 0x15, 0x94, 0x0d, 0x0a, 0x4c, 0x04, 0x4d, 0xe0, 0xad, 0x3c, 0x7d, 0x8c, 0x33, 0x13, 0x7c, + 0x35, 0x8d, 0xb6, 0x41, 0xda, 0x04, 0xfe, 0x0d, 0x80, 0xda, 0x1b, 0x99, 0xc0, 0x70, 0xb3, 0x49, + 0x7c, 0x95, 0x4a, 0x27, 0x0c, 0x35, 0x38, 0x4f, 0x55, 0x91, 0xd3, 0x6a, 0x12, 0x8a, 0xf4, 0x60, + 0x22, 0x09, 0x7c, 0x08, 0xe6, 0x03, 0xcf, 0x24, 0xa7, 0x76, 0x4f, 0x26, 0xde, 0x09, 0x77, 0x64, + 0xc2, 0x52, 0xbb, 0x83, 0xa0, 0x36, 0x8c, 0xc9, 0xe0, 0x2d, 0x30, 0x4f, 0x7b, 0xd6, 0x91, 0xe3, + 0xda, 0xde, 0x11, 0xb3, 0xf0, 0x21, 0x76, 0xda, 0xa2, 0xfb, 0xd0, 0xe9, 0x18, 0xd2, 0xde, 0x33, + 0xa5, 0xaa, 0x05, 0x9a, 0x85, 0xff, 0x30, 0x00, 0x88, 0xf9, 0xb3, 0x04, 0x66, 0x7d, 0x95, 0x44, + 0xe5, 0x89, 0xcf, 0xd6, 0x53, 0x83, 0x2f, 0x2a, 0xd3, 0x7e, 0xa6, 0xf7, 0x0a, 0x0a, 0x14, 0xf0, + 0x87, 0x60, 0x36, 0x70, 0x33, 0xf9, 0x95, 0x6e, 0xea, 0xf3, 0x1b, 0x58, 0xc0, 0xb7, 0xce, 0x7f, + 0x09, 0xa8, 0x2c, 0x25, 0x5c, 0xa7, 0xeb, 0x7f, 0x36, 0x41, 0x3a, 0x2c, 0x8b, 0xe1, 0x3b, 0xf1, + 0xf2, 0xf9, 0xc6, 0xa9, 0xe5, 0xf3, 0x19, 0x75, 0xf3, 0x3a, 0x00, 0x4d, 0x4a, 0xb0, 0xbe, 0xaf, + 0x4b, 0x5e, 0xe4, 0xbe, 0x4e, 0xdb, 0xd5, 0xb8, 0x20, 0xe9, 0xfa, 0x76, 0x40, 0x32, 0x75, 0x11, + 0x12, 0x6d, 0x57, 0xe3, 0x61, 0x2f, 0x35, 0x1d, 0x6b, 0xf1, 0x16, 0x41, 0xc6, 0x26, 0xac, 0x49, + 0x1d, 0x5f, 0x9c, 0x09, 0x19, 0x3e, 0xd2, 0x28, 0x2e, 0x82, 0x9b, 0x00, 0x60, 0xce, 0xa9, 0xb3, + 0xdb, 0xe5, 0x84, 0x99, 0x33, 0x72, 0x47, 0xbf, 0x71, 0xea, 0x44, 0x54, 0x6b, 0x21, 0x76, 0xc3, + 0xe5, 0xf4, 0x18, 0xc5, 0x8c, 0xe1, 0xcf, 0x40, 0x46, 0xc7, 0x42, 0x4b, 0x4c, 0xea, 0xec, 0xc5, + 0x7b, 0x12, 0x79, 0xbf, 0x16, 0xc8, 0x1b, 0x0c, 0x81, 0xc3, 0x00, 0xc3, 0x60, 0x1d, 0x40, 0x46, + 0xa8, 0x0c, 0xd6, 0x3e, 0xf5, 0xf6, 0x9c, 0x36, 0x11, 0x55, 0x7e, 0x4a, 0x56, 0xf9, 0xf2, 0x5e, + 0xf0, 0xb1, 0xd2, 0xee, 0x28, 0xe5, 0x66, 0x03, 0x15, 0xd9, 0xb0, 0xc4, 0x86, 0x77, 0xc1, 0x15, + 0x7d, 0xe5, 0x6c, 0x09, 0x1d, 0xa1, 0xf2, 0x8a, 0x9a, 0x30, 0x26, 0x53, 0x6f, 0x1a, 0xcd, 0x6b, + 0xed, 0x63, 0xa9, 0xac, 0x29, 0x1d, 0xfc, 0x11, 0x58, 0x88, 0x07, 0xa8, 0x11, 0x4b, 0x20, 0x2d, + 0xcd, 0x18, 0x62, 0xd8, 0xba, 0x0a, 0xe6, 0xe4, 0xb1, 0x1c, 0x31, 0xcb, 0x48, 0xb3, 0x92, 0x50, + 0x0d, 0xe3, 0x1f, 0x80, 0x74, 0xdb, 0x53, 0x44, 0xcc, 0xcc, 0xca, 0xf5, 0x58, 0x3e, 0x7d, 0x3d, + 0xb6, 0x02, 0xa8, 0x5a, 0x8e, 0xc8, 0x74, 0x62, 0xef, 0x92, 0x3b, 0x77, 0xef, 0x92, 0x9f, 0xd8, + 0xbb, 0x4c, 0xc8, 0x7a, 0x85, 0x6f, 0xb3, 0x49, 0x2c, 0x7e, 0xdb, 0x4d, 0x62, 0xe9, 0x02, 0x4d, + 0xe2, 0xe9, 0x8d, 0x1b, 0xfc, 0x7f, 0x69, 0xdc, 0xe6, 0xce, 0xd3, 0xb8, 0xcd, 0x9f, 0xa3, 0x71, + 0xbb, 0x7c, 0xbe, 0xc6, 0xed, 0xca, 0xd7, 0x6d, 0xdc, 0xae, 0x9e, 0xbb, 0x71, 0x33, 0x4f, 0x69, + 0xdc, 0xde, 0x02, 0x69, 0xea, 0x79, 0xdc, 0x92, 0x61, 0xfe, 0x25, 0x39, 0xbb, 0xe6, 0x58, 0x29, + 0xeb, 0x79, 0x5c, 0xc4, 0x78, 0x94, 0xa2, 0xfa, 0x09, 0x7e, 0x00, 0x66, 0x5c, 0xc2, 0xc5, 0xba, + 0x2e, 0xc8, 0xc4, 0x73, 0xff, 0x4f, 0xfd, 0xca, 0xda, 0x85, 0x7e, 0x70, 0xda, 0x26, 0x7c, 0xb3, + 0x31, 0xe8, 0x57, 0x2e, 0xc9, 0x07, 0x74, 0xc9, 0x25, 0x5c, 0x5e, 0x10, 0x65, 0xc5, 0x8a, 0x33, + 0x5d, 0xdd, 0x9b, 0x2f, 0x4f, 0x4e, 0x3c, 0xb1, 0x06, 0x40, 0xdd, 0xe0, 0xc7, 0x04, 0x28, 0xd3, + 0xc1, 0xcd, 0xb0, 0x47, 0x5c, 0x07, 0x69, 0x49, 0x28, 0x92, 0xbb, 0x79, 0x6d, 0xf2, 0xf8, 0x82, + 0xe4, 0x5f, 0xcf, 0x0e, 0xfa, 0x95, 0xb0, 0xb4, 0x46, 0x29, 0xc1, 0x23, 0x8b, 0xec, 0xdb, 0x60, + 0x96, 0xa9, 0x54, 0x67, 0xbe, 0x22, 0x29, 0xae, 0x9e, 0x92, 0x09, 0x51, 0x80, 0x83, 0xef, 0x80, + 0xa0, 0x20, 0xb1, 0x02, 0xd3, 0xf2, 0xd9, 0xa6, 0x79, 0x8d, 0x0f, 0x7e, 0xd9, 0xbb, 0x01, 0xf2, + 0x61, 0xfd, 0x28, 0x17, 0xd1, 0xac, 0xc8, 0xaa, 0x31, 0xab, 0xab, 0x46, 0xb9, 0x80, 0xf0, 0x75, + 0x50, 0xe8, 0x32, 0x62, 0x47, 0x28, 0x66, 0x2e, 0x2e, 0x4e, 0x2d, 0xe7, 0xe4, 0xd6, 0xb1, 0x03, + 0x18, 0x13, 0x38, 0xc9, 0x16, 0xed, 0x09, 0xf3, 0xd5, 0xe8, 0x47, 0xb4, 0x70, 0x43, 0xc0, 0xef, + 0x6b, 0x1c, 0xfd, 0x44, 0xb7, 0x82, 0xb7, 0xcc, 0x25, 0xd9, 0x33, 0x17, 0x07, 0xfd, 0x4a, 0x76, + 0x0b, 0x33, 0x8e, 0xde, 0x93, 0x4d, 0xe0, 0x2d, 0xe5, 0x08, 0xfa, 0x44, 0xbd, 0x8d, 0x1b, 0xde, + 0x36, 0xaf, 0x4f, 0x34, 0xbc, 0x3d, 0x64, 0x78, 0x1b, 0x7e, 0x0c, 0x5e, 0x1e, 0xad, 0x93, 0x29, + 0x69, 0x12, 0xe7, 0x50, 0xa5, 0xe8, 0x1b, 0x17, 0xa9, 0xc3, 0xc3, 0x62, 0x1a, 0x69, 0x86, 0x9a, + 0x38, 0x71, 0x19, 0xf5, 0xd3, 0x94, 0xda, 0x03, 0xaf, 0x9d, 0x12, 0xe8, 0x04, 0x44, 0xad, 0x3b, + 0xf0, 0xc3, 0x67, 0xb8, 0x02, 0xe0, 0xae, 0xbc, 0x83, 0x38, 0x16, 0xb5, 0x78, 0x93, 0xb8, 0x1c, + 0xb7, 0x88, 0xf9, 0xfa, 0xa2, 0xb1, 0x9c, 0x44, 0x25, 0xad, 0xd9, 0x09, 0x15, 0xf0, 0x3b, 0xa0, + 0x10, 0xf6, 0x10, 0xfa, 0xc6, 0xe1, 0x3b, 0x8b, 0xc6, 0xf2, 0x25, 0x94, 0x0f, 0xc4, 0xfa, 0x9e, + 0x01, 0x8b, 0x43, 0x2a, 0xac, 0x2c, 0x6c, 0x53, 0x7d, 0x07, 0xcd, 0xcc, 0x65, 0x99, 0x83, 0xc6, + 0xa2, 0x9b, 0xba, 0x8e, 0xd6, 0xb7, 0x26, 0x2a, 0x03, 0x23, 0x69, 0x5c, 0x6b, 0x20, 0xa5, 0x63, + 0xe2, 0x64, 0x4b, 0x89, 0x4d, 0xb5, 0x04, 0x36, 0x40, 0x5e, 0x7f, 0x22, 0xa0, 0x7f, 0xe3, 0x1c, + 0xf4, 0x28, 0xa7, 0x8c, 0x02, 0x96, 0xf7, 0x80, 0x66, 0x0e, 0xbb, 0x05, 0x66, 0xbe, 0x29, 0x79, + 0x2a, 0x63, 0xcd, 0x6a, 0x30, 0x44, 0xcd, 0x54, 0x50, 0x86, 0x81, 0x98, 0x89, 0x36, 0x44, 0x57, + 0xe4, 0x93, 0xba, 0x10, 0x66, 0x7e, 0x57, 0xf2, 0x9e, 0xaf, 0x0d, 0x51, 0x44, 0x13, 0x54, 0x0c, + 0xbe, 0x0b, 0x40, 0xec, 0x0e, 0xea, 0xe6, 0xc5, 0xee, 0xa0, 0x50, 0xcc, 0x16, 0x62, 0x90, 0xf7, + 0xa9, 0x77, 0xe8, 0x88, 0xf3, 0x48, 0xa8, 0x88, 0x76, 0x2b, 0x32, 0x8b, 0xdd, 0x13, 0x91, 0x7a, + 0x27, 0xd2, 0x5c, 0xe4, 0xea, 0x3a, 0x17, 0x63, 0xdc, 0xb4, 0x61, 0x03, 0x94, 0x42, 0x81, 0x08, + 0x16, 0x36, 0xe6, 0xd8, 0xac, 0xea, 0x48, 0x31, 0xba, 0xe7, 0x1f, 0xcb, 0x7f, 0x86, 0x40, 0xc5, + 0xb8, 0x45, 0x03, 0x73, 0xbc, 0xf0, 0x63, 0x50, 0x18, 0x29, 0x17, 0x61, 0x11, 0x4c, 0x1d, 0x10, + 0xf5, 0x53, 0x4e, 0x1a, 0x89, 0x47, 0x38, 0x1f, 0x5c, 0x36, 0xa8, 0x5f, 0x26, 0xd4, 0xcb, 0xbd, + 0xe4, 0xdb, 0xc6, 0xc2, 0x07, 0x20, 0x3f, 0x5c, 0xdd, 0x4c, 0xb0, 0xae, 0xc6, 0xad, 0x27, 0x04, + 0xd1, 0x80, 0x20, 0xc6, 0xab, 0xfb, 0x80, 0x77, 0x01, 0x08, 0xab, 0x28, 0x06, 0xef, 0x81, 0x4c, + 0xf4, 0xcf, 0x2c, 0xa2, 0x1f, 0x98, 0x92, 0x77, 0x57, 0xa7, 0x95, 0x5d, 0x08, 0x90, 0xd0, 0x76, + 0xe9, 0x67, 0xe0, 0xca, 0xba, 0xac, 0xe4, 0x23, 0xb5, 0x6e, 0x54, 0xea, 0x00, 0x44, 0xac, 0xba, + 0xc9, 0x38, 0x9d, 0x34, 0xd6, 0x59, 0xa4, 0x43, 0xfa, 0xa5, 0x7f, 0x33, 0xc0, 0x95, 0xa7, 0xb2, + 0xc6, 0xff, 0x36, 0xe8, 0xe1, 0x7d, 0x00, 0xa2, 0x7f, 0x77, 0x39, 0xb5, 0x7d, 0x79, 0x20, 0x20, + 0x0f, 0x31, 0x3b, 0xd0, 0x0d, 0x55, 0x7a, 0x2f, 0x10, 0x2c, 0xfd, 0xb7, 0x01, 0xe6, 0x7e, 0x42, + 0xf8, 0x98, 0x73, 0x4f, 0x40, 0x3e, 0x72, 0xce, 0xfa, 0xfa, 0x4d, 0x56, 0x96, 0x44, 0x7a, 0xf6, + 0xcd, 0xdd, 0xfd, 0x1f, 0x03, 0x5c, 0xde, 0x72, 0x58, 0xe4, 0x2f, 0x0b, 0x1c, 0xfe, 0x10, 0x14, + 0xe2, 0x01, 0x20, 0xf2, 0xf8, 0xf5, 0x33, 0x8e, 0xfe, 0x64, 0x9f, 0xf3, 0x38, 0x8e, 0xf8, 0xe6, + 0x5e, 0x8b, 0x43, 0xe2, 0x51, 0x9b, 0x50, 0xfd, 0x2b, 0x92, 0x7a, 0x91, 0x3f, 0xd2, 0xc9, 0xff, + 0x34, 0x50, 0xff, 0xc9, 0xa2, 0x5e, 0x44, 0x1b, 0xe8, 0x8b, 0x74, 0xa0, 0xfe, 0x6f, 0x45, 0x3e, + 0x2f, 0xfd, 0xca, 0x00, 0x73, 0x8f, 0x27, 0x2c, 0xd2, 0xf7, 0xc1, 0xcc, 0x79, 0x77, 0x8f, 0xf2, + 0x49, 0xc3, 0xbf, 0xf1, 0x88, 0xde, 0x7c, 0x00, 0x40, 0x94, 0xdc, 0x60, 0x09, 0xe4, 0x76, 0x1e, + 0x3d, 0xdb, 0x40, 0xd6, 0xd3, 0xed, 0xf7, 0xb7, 0x1f, 0x3d, 0xdb, 0x2e, 0x26, 0x22, 0x51, 0xbd, + 0xf6, 0xe4, 0xc9, 0x06, 0xfa, 0xb0, 0x68, 0x40, 0x08, 0xf2, 0x4a, 0xb4, 0xf1, 0xb7, 0x4f, 0x36, + 0xd0, 0x76, 0x6d, 0xab, 0x98, 0xac, 0xff, 0xbb, 0xf1, 0xd9, 0x8b, 0xb2, 0xf1, 0xf9, 0x8b, 0xb2, + 0xf1, 0xc7, 0x17, 0xe5, 0xc4, 0x9f, 0x5f, 0x94, 0x13, 0x7f, 0x79, 0x51, 0x4e, 0xfc, 0xf5, 0x45, + 0x39, 0xf1, 0xe5, 0x8b, 0xb2, 0xf1, 0x8b, 0x41, 0xd9, 0xf8, 0xe5, 0xa0, 0x9c, 0xf8, 0xdd, 0xa0, + 0x6c, 0xfc, 0x7e, 0x50, 0x4e, 0x7c, 0x3a, 0x28, 0x27, 0xfe, 0x30, 0x28, 0x27, 0x3e, 0x1b, 0x94, + 0x8d, 0xcf, 0x07, 0x65, 0xe3, 0x8f, 0x83, 0x72, 0xe2, 0xcf, 0x83, 0xb2, 0xf1, 0x97, 0x41, 0x39, + 0xf1, 0xd7, 0x41, 0xd9, 0xf8, 0x72, 0x50, 0x4e, 0xfc, 0xe2, 0xa4, 0x9c, 0xf8, 0xe5, 0x49, 0xd9, + 0xf8, 0xf5, 0x49, 0x39, 0xf1, 0x9b, 0x93, 0xb2, 0xf1, 0xdb, 0x93, 0x72, 0xe2, 0x77, 0x27, 0xe5, + 0xc4, 0xef, 0x4f, 0xca, 0xc6, 0xa7, 0x27, 0x65, 0xe3, 0x0f, 0x27, 0x65, 0xe3, 0xa7, 0x37, 0xcf, + 0x5b, 0x55, 0x72, 0xd7, 0xdf, 0xdd, 0x9d, 0x91, 0x33, 0x72, 0xe7, 0x7f, 0x03, 0x00, 0x00, 0xff, + 0xff, 0x6f, 0xf4, 0x9e, 0xcd, 0x43, 0x27, 0x00, 0x00, } diff --git a/pkg/ttnpb/end_device.validator.pb.go b/pkg/ttnpb/end_device.validator.pb.go index 639424275b..a9c7a38426 100644 --- a/pkg/ttnpb/end_device.validator.pb.go +++ b/pkg/ttnpb/end_device.validator.pb.go @@ -12,6 +12,7 @@ import _ "github.com/gogo/protobuf/gogoproto" import _ "github.com/golang/protobuf/ptypes/duration" import _ "github.com/golang/protobuf/ptypes/struct" import _ "github.com/golang/protobuf/ptypes/timestamp" +import _ "github.com/golang/protobuf/ptypes/wrappers" import _ "github.com/mwitkow/go-proto-validators" import _ "google.golang.org/genproto/googleapis/api/annotations" import _ "google.golang.org/genproto/protobuf/field_mask" @@ -95,6 +96,27 @@ func (this *MACSettings) Validate() error { if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(&(this.StatusTimePeriodicity)); err != nil { return github_com_mwitkow_go_proto_validators.FieldError("StatusTimePeriodicity", err) } + if this.Rx1Delay != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Rx1Delay); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("Rx1Delay", err) + } + } + if this.Rx2DataRateIndex != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Rx2DataRateIndex); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("Rx2DataRateIndex", err) + } + } + if this.Rx2Frequency != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Rx2Frequency); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("Rx2Frequency", err) + } + } + return nil +} +func (this *MACSettings_RxDelayValue) Validate() error { + return nil +} +func (this *MACSettings_DataRateIndexValue) Validate() error { return nil } func (this *MACState) Validate() error { From 5f9c65d6610dc9f3e9eb518de92cfc8eaff0c446 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 5 Feb 2019 13:47:20 +0100 Subject: [PATCH 03/40] ns: Set desired parameters on reset if specified in MACSettings --- pkg/networkserver/grpc_gsns.go | 2 ++ pkg/networkserver/grpc_gsns_test.go | 7 +++++++ pkg/networkserver/mac_reset_test.go | 6 ++++++ pkg/networkserver/utils.go | 12 ++++++++++++ pkg/networkserver/utils_internal_test.go | 14 ++++++++++++-- 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/pkg/networkserver/grpc_gsns.go b/pkg/networkserver/grpc_gsns.go index 6862812b4b..6758e2b212 100644 --- a/pkg/networkserver/grpc_gsns.go +++ b/pkg/networkserver/grpc_gsns.go @@ -737,6 +737,7 @@ func (ns *NetworkServer) handleJoin(ctx context.Context, up *ttnpb.UplinkMessage "frequency_plan_id", "lorawan_phy_version", "lorawan_version", + "mac_settings", "mac_state", "session", }, @@ -822,6 +823,7 @@ func (ns *NetworkServer) handleJoin(ctx context.Context, up *ttnpb.UplinkMessage "frequency_plan_id", "lorawan_phy_version", "lorawan_version", + "mac_settings", "mac_state", "pending_session", "queued_application_downlinks", diff --git a/pkg/networkserver/grpc_gsns_test.go b/pkg/networkserver/grpc_gsns_test.go index 8d88e0b483..538821f129 100644 --- a/pkg/networkserver/grpc_gsns_test.go +++ b/pkg/networkserver/grpc_gsns_test.go @@ -187,6 +187,7 @@ func handleUplinkTest() func(t *testing.T) { }, LoRaWANVersion: ttnpb.MAC_V1_1, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, + MACSettings: &ttnpb.MACSettings{}, Session: &ttnpb.Session{ DevAddr: DevAddr, SessionKeys: ttnpb.SessionKeys{ @@ -251,6 +252,7 @@ func handleUplinkTest() func(t *testing.T) { }, LoRaWANVersion: ttnpb.MAC_V1_1, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, + MACSettings: &ttnpb.MACSettings{}, Session: &ttnpb.Session{ DevAddr: DevAddr, SessionKeys: ttnpb.SessionKeys{ @@ -1441,6 +1443,7 @@ func handleJoinTest() func(t *testing.T) { DeviceID: DeviceID, }, FrequencyPlanID: test.EUFrequencyPlanID, + MACSettings: &ttnpb.MACSettings{}, }, func() *ttnpb.UplinkMessage { msg := ttnpb.NewPopulatedUplinkMessageJoinRequest(test.Randy) @@ -1468,6 +1471,7 @@ func handleJoinTest() func(t *testing.T) { FrequencyPlanID: test.EUFrequencyPlanID, Session: ttnpb.NewPopulatedSession(test.Randy, false), MACState: ttnpb.NewPopulatedMACState(test.Randy, false), + MACSettings: &ttnpb.MACSettings{}, }, func() *ttnpb.UplinkMessage { msg := ttnpb.NewPopulatedUplinkMessageJoinRequest(test.Randy) @@ -1495,6 +1499,7 @@ func handleJoinTest() func(t *testing.T) { FrequencyPlanID: test.EUFrequencyPlanID, Session: ttnpb.NewPopulatedSession(test.Randy, false), MACState: ttnpb.NewPopulatedMACState(test.Randy, false), + MACSettings: &ttnpb.MACSettings{}, }, func() *ttnpb.UplinkMessage { msg := ttnpb.NewPopulatedUplinkMessageJoinRequest(test.Randy) @@ -1522,6 +1527,7 @@ func handleJoinTest() func(t *testing.T) { FrequencyPlanID: test.EUFrequencyPlanID, Session: ttnpb.NewPopulatedSession(test.Randy, false), MACState: ttnpb.NewPopulatedMACState(test.Randy, false), + MACSettings: &ttnpb.MACSettings{}, }, func() *ttnpb.UplinkMessage { msg := ttnpb.NewPopulatedUplinkMessageJoinRequest(test.Randy) @@ -1549,6 +1555,7 @@ func handleJoinTest() func(t *testing.T) { FrequencyPlanID: test.EUFrequencyPlanID, Session: ttnpb.NewPopulatedSession(test.Randy, false), MACState: ttnpb.NewPopulatedMACState(test.Randy, false), + MACSettings: &ttnpb.MACSettings{}, }, func() *ttnpb.UplinkMessage { msg := ttnpb.NewPopulatedUplinkMessageJoinRequest(test.Randy) diff --git a/pkg/networkserver/mac_reset_test.go b/pkg/networkserver/mac_reset_test.go index 4db3a25854..fe1eff51d9 100644 --- a/pkg/networkserver/mac_reset_test.go +++ b/pkg/networkserver/mac_reset_test.go @@ -41,11 +41,13 @@ func TestHandleResetInd(t *testing.T) { LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, SupportsJoin: false, MACState: &ttnpb.MACState{}, + MACSettings: &ttnpb.MACSettings{}, }, Expected: &ttnpb.EndDevice{ LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, SupportsJoin: false, MACState: &ttnpb.MACState{}, + MACSettings: &ttnpb.MACSettings{}, }, AssertEvents: func(t *testing.T, evs ...events.Event) bool { return assertions.New(t).So(evs, should.BeEmpty) @@ -66,6 +68,7 @@ func TestHandleResetInd(t *testing.T) { DesiredParameters: *ttnpb.NewPopulatedMACParameters(test.Randy, false), QueuedResponses: []*ttnpb.MACCommand{}, }, + MACSettings: &ttnpb.MACSettings{}, }, Expected: func() *ttnpb.EndDevice { dev := &ttnpb.EndDevice{ @@ -75,6 +78,7 @@ func TestHandleResetInd(t *testing.T) { LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, SupportsJoin: false, FrequencyPlanID: test.EUFrequencyPlanID, + MACSettings: &ttnpb.MACSettings{}, } if err := ResetMACState(dev, frequencyplans.NewStore(test.FrequencyPlansFetcher)); err != nil { t.Fatalf("Failed to reset MACState: %v", errors.Stack(err)) @@ -122,6 +126,7 @@ func TestHandleResetInd(t *testing.T) { {}, }, }, + MACSettings: &ttnpb.MACSettings{}, }, Expected: func() *ttnpb.EndDevice { dev := &ttnpb.EndDevice{ @@ -131,6 +136,7 @@ func TestHandleResetInd(t *testing.T) { LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, SupportsJoin: false, FrequencyPlanID: test.EUFrequencyPlanID, + MACSettings: &ttnpb.MACSettings{}, } if err := ResetMACState(dev, frequencyplans.NewStore(test.FrequencyPlansFetcher)); err != nil { t.Fatalf("Failed to reset MACState: %v", errors.Stack(err)) diff --git a/pkg/networkserver/utils.go b/pkg/networkserver/utils.go index 023c11cbd3..3f20a29945 100644 --- a/pkg/networkserver/utils.go +++ b/pkg/networkserver/utils.go @@ -178,6 +178,18 @@ outerDown: dev.MACState.DesiredParameters.MaxEIRP = float32(math.Min(float64(dev.MACState.CurrentParameters.MaxEIRP), float64(*fp.MaxEIRP))) } + if dev.MACSettings.Rx1Delay != nil { + dev.MACState.DesiredParameters.Rx1Delay = dev.MACSettings.Rx1Delay.Value + } + + if dev.MACSettings.Rx2Frequency != nil { + dev.MACState.DesiredParameters.Rx2Frequency = dev.MACSettings.Rx2Frequency.Value + } + + if dev.MACSettings.Rx2DataRateIndex != nil { + dev.MACState.DesiredParameters.Rx2DataRateIndex = dev.MACSettings.Rx2DataRateIndex.Value + } + if dev.DefaultMACParameters != nil { dev.MACState.CurrentParameters = deepcopy.Copy(*dev.DefaultMACParameters).(ttnpb.MACParameters) } diff --git a/pkg/networkserver/utils_internal_test.go b/pkg/networkserver/utils_internal_test.go index fade67f58b..c9537f7dd5 100644 --- a/pkg/networkserver/utils_internal_test.go +++ b/pkg/networkserver/utils_internal_test.go @@ -40,6 +40,11 @@ func TestResetMACState(t *testing.T) { FrequencyPlanID: test.EUFrequencyPlanID, LoRaWANVersion: ttnpb.MAC_V1_1, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, + MACSettings: &ttnpb.MACSettings{ + Rx1Delay: &ttnpb.MACSettings_RxDelayValue{ + Value: ttnpb.RX_DELAY_13, + }, + }, }, DeviceDiff: func(dev *ttnpb.EndDevice) { fp := test.Must(frequencyplans.NewStore(test.FrequencyPlansFetcher).GetByID(test.EUFrequencyPlanID)).(*frequencyplans.FrequencyPlan) @@ -106,7 +111,7 @@ func TestResetMACState(t *testing.T) { RejoinCountPeriodicity: ttnpb.REJOIN_COUNT_16, RejoinTimePeriodicity: ttnpb.REJOIN_TIME_0, Rx1DataRateOffset: 0, - Rx1Delay: ttnpb.RxDelay(band.ReceiveDelay1.Seconds()), + Rx1Delay: ttnpb.RX_DELAY_13, Rx2DataRateIndex: band.DefaultRx2Parameters.DataRateIndex, Rx2Frequency: band.DefaultRx2Parameters.Frequency, UplinkDwellTime: false, @@ -186,6 +191,11 @@ func TestResetMACState(t *testing.T) { FrequencyPlanID: test.USFrequencyPlanID, LoRaWANVersion: ttnpb.MAC_V1_1, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, + MACSettings: &ttnpb.MACSettings{ + Rx1Delay: &ttnpb.MACSettings_RxDelayValue{ + Value: ttnpb.RX_DELAY_13, + }, + }, }, DeviceDiff: func() func(dev *ttnpb.EndDevice) { var bandChannels []*ttnpb.MACParameters_Channel @@ -252,7 +262,7 @@ func TestResetMACState(t *testing.T) { RejoinCountPeriodicity: ttnpb.REJOIN_COUNT_16, RejoinTimePeriodicity: ttnpb.REJOIN_TIME_0, Rx1DataRateOffset: 0, - Rx1Delay: ttnpb.RxDelay(band.ReceiveDelay1.Seconds()), + Rx1Delay: ttnpb.RX_DELAY_13, Rx2DataRateIndex: band.DefaultRx2Parameters.DataRateIndex, Rx2Frequency: band.DefaultRx2Parameters.Frequency, UplinkDwellTime: false, From 440bec55cab1c604ba3af13b44b3e851c7516dae Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 5 Feb 2019 15:03:54 +0100 Subject: [PATCH 04/40] ns: Default to RxDelay of 5 --- pkg/networkserver/utils.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/networkserver/utils.go b/pkg/networkserver/utils.go index 3f20a29945..8b2be26101 100644 --- a/pkg/networkserver/utils.go +++ b/pkg/networkserver/utils.go @@ -160,6 +160,9 @@ outerDown: dev.MACState.DesiredParameters.UplinkDwellTime = fp.DwellTime.GetUplinks() dev.MACState.DesiredParameters.DownlinkDwellTime = fp.DwellTime.GetDownlinks() + // TODO: Apply NS-wide default (https://github.com/TheThingsIndustries/lorawan-stack/issues/1544) + dev.MACState.DesiredParameters.Rx1Delay = ttnpb.RX_DELAY_5 + if fp.Rx2Channel != nil { dev.MACState.DesiredParameters.Rx2Frequency = fp.Rx2Channel.Frequency } From f4322d76f8edd623d6b27bdddbe262729665ea75 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 6 Feb 2019 14:03:38 +0100 Subject: [PATCH 05/40] api: Make MACSettings optional --- api/api.md | 6 +- api/end_device.proto | 12 +- pkg/ttnpb/end_device.pb.fm.go | 18 +- pkg/ttnpb/end_device.pb.go | 1017 ++++++++++++++------------ pkg/ttnpb/end_device.validator.pb.go | 33 +- 5 files changed, 602 insertions(+), 484 deletions(-) diff --git a/api/api.md b/api/api.md index 1e223a5fe8..4d690e2a04 100644 --- a/api/api.md +++ b/api/api.md @@ -1784,12 +1784,12 @@ This is used internally by the Network Server and is read only. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| use_adr | [bool](#bool) | | | -| adr_margin | [uint32](#uint32) | | The ADR margin tells the network server how much margin it should add in ADR requests. A bigger margin is less efficient, but gives a better chance of successful reception. | +| use_adr | [google.protobuf.BoolValue](#google.protobuf.BoolValue) | | | +| adr_margin | [google.protobuf.UInt32Value](#google.protobuf.UInt32Value) | | The ADR margin tells the network server how much margin it should add in ADR requests. A bigger margin is less efficient, but gives a better chance of successful reception. | | class_b_timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | Deadline for the device to respond to requests from the Network Server. | | class_c_timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | Deadline for the device to respond to requests from the Network Server. | | status_time_periodicity | [google.protobuf.Duration](#google.protobuf.Duration) | | The interval after which a DevStatusReq MACCommand shall be sent. | -| status_count_periodicity | [uint32](#uint32) | | Number of uplink messages after which a DevStatusReq MACCommand shall be sent. | +| status_count_periodicity | [google.protobuf.UInt32Value](#google.protobuf.UInt32Value) | | Number of uplink messages after which a DevStatusReq MACCommand shall be sent. | | rx1_delay | [MACSettings.RxDelayValue](#ttn.lorawan.v3.MACSettings.RxDelayValue) | | | | rx2_data_rate_index | [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) | | | | rx2_frequency | [google.protobuf.UInt64Value](#google.protobuf.UInt64Value) | | | diff --git a/api/end_device.proto b/api/end_device.proto index 9504c82de4..b57b5cca16 100644 --- a/api/end_device.proto +++ b/api/end_device.proto @@ -176,18 +176,18 @@ message EndDeviceVersion { } message MACSettings { - bool use_adr = 1 [(gogoproto.customname) = "UseADR"]; + google.protobuf.BoolValue use_adr = 1 [(gogoproto.customname) = "UseADR"]; // The ADR margin tells the network server how much margin it should add in ADR requests. // A bigger margin is less efficient, but gives a better chance of successful reception. - uint32 adr_margin = 2 [(gogoproto.customname) = "ADRMargin"]; + google.protobuf.UInt32Value adr_margin = 2 [(gogoproto.customname) = "ADRMargin"]; // Deadline for the device to respond to requests from the Network Server. - google.protobuf.Duration class_b_timeout = 3 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false]; + google.protobuf.Duration class_b_timeout = 3 [(gogoproto.stdduration) = true]; // Deadline for the device to respond to requests from the Network Server. - google.protobuf.Duration class_c_timeout = 4 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false]; + google.protobuf.Duration class_c_timeout = 4 [(gogoproto.stdduration) = true]; // The interval after which a DevStatusReq MACCommand shall be sent. - google.protobuf.Duration status_time_periodicity = 5 [(gogoproto.stdduration) = true, (gogoproto.nullable) = false]; + google.protobuf.Duration status_time_periodicity = 5 [(gogoproto.stdduration) = true]; // Number of uplink messages after which a DevStatusReq MACCommand shall be sent. - uint32 status_count_periodicity = 6; + google.protobuf.UInt32Value status_count_periodicity = 6; message RxDelayValue { RxDelay value = 1; diff --git a/pkg/ttnpb/end_device.pb.fm.go b/pkg/ttnpb/end_device.pb.fm.go index f8f288e2ef..25e2bd92bb 100644 --- a/pkg/ttnpb/end_device.pb.fm.go +++ b/pkg/ttnpb/end_device.pb.fm.go @@ -921,8 +921,7 @@ func (dst *MACSettings) SetFields(src *MACSettings, paths ...string) error { if src != nil { dst.UseADR = src.UseADR } else { - var zero bool - dst.UseADR = zero + dst.UseADR = nil } case "adr_margin": if len(subs) > 0 { @@ -931,8 +930,7 @@ func (dst *MACSettings) SetFields(src *MACSettings, paths ...string) error { if src != nil { dst.ADRMargin = src.ADRMargin } else { - var zero uint32 - dst.ADRMargin = zero + dst.ADRMargin = nil } case "class_b_timeout": if len(subs) > 0 { @@ -941,8 +939,7 @@ func (dst *MACSettings) SetFields(src *MACSettings, paths ...string) error { if src != nil { dst.ClassBTimeout = src.ClassBTimeout } else { - var zero time.Duration - dst.ClassBTimeout = zero + dst.ClassBTimeout = nil } case "class_c_timeout": if len(subs) > 0 { @@ -951,8 +948,7 @@ func (dst *MACSettings) SetFields(src *MACSettings, paths ...string) error { if src != nil { dst.ClassCTimeout = src.ClassCTimeout } else { - var zero time.Duration - dst.ClassCTimeout = zero + dst.ClassCTimeout = nil } case "status_time_periodicity": if len(subs) > 0 { @@ -961,8 +957,7 @@ func (dst *MACSettings) SetFields(src *MACSettings, paths ...string) error { if src != nil { dst.StatusTimePeriodicity = src.StatusTimePeriodicity } else { - var zero time.Duration - dst.StatusTimePeriodicity = zero + dst.StatusTimePeriodicity = nil } case "status_count_periodicity": if len(subs) > 0 { @@ -971,8 +966,7 @@ func (dst *MACSettings) SetFields(src *MACSettings, paths ...string) error { if src != nil { dst.StatusCountPeriodicity = src.StatusCountPeriodicity } else { - var zero uint32 - dst.StatusCountPeriodicity = zero + dst.StatusCountPeriodicity = nil } case "rx1_delay": if len(subs) > 0 { diff --git a/pkg/ttnpb/end_device.pb.go b/pkg/ttnpb/end_device.pb.go index fdc891f535..b681a5c86e 100644 --- a/pkg/ttnpb/end_device.pb.go +++ b/pkg/ttnpb/end_device.pb.go @@ -62,7 +62,7 @@ var PowerState_value = map[string]int32{ } func (PowerState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{0} + return fileDescriptor_end_device_1fd831da224133be, []int{0} } type Session struct { @@ -87,7 +87,7 @@ type Session struct { func (m *Session) Reset() { *m = Session{} } func (*Session) ProtoMessage() {} func (*Session) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{0} + return fileDescriptor_end_device_1fd831da224133be, []int{0} } func (m *Session) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -199,7 +199,7 @@ type MACParameters struct { func (m *MACParameters) Reset() { *m = MACParameters{} } func (*MACParameters) ProtoMessage() {} func (*MACParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{1} + return fileDescriptor_end_device_1fd831da224133be, []int{1} } func (m *MACParameters) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -379,7 +379,7 @@ type MACParameters_Channel struct { func (m *MACParameters_Channel) Reset() { *m = MACParameters_Channel{} } func (*MACParameters_Channel) ProtoMessage() {} func (*MACParameters_Channel) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{1, 0} + return fileDescriptor_end_device_1fd831da224133be, []int{1, 0} } func (m *MACParameters_Channel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -456,7 +456,7 @@ type EndDeviceBrand struct { func (m *EndDeviceBrand) Reset() { *m = EndDeviceBrand{} } func (*EndDeviceBrand) ProtoMessage() {} func (*EndDeviceBrand) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{2} + return fileDescriptor_end_device_1fd831da224133be, []int{2} } func (m *EndDeviceBrand) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -524,7 +524,7 @@ type EndDeviceModel struct { func (m *EndDeviceModel) Reset() { *m = EndDeviceModel{} } func (*EndDeviceModel) ProtoMessage() {} func (*EndDeviceModel) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{3} + return fileDescriptor_end_device_1fd831da224133be, []int{3} } func (m *EndDeviceModel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -587,7 +587,7 @@ type EndDeviceVersionIdentifiers struct { func (m *EndDeviceVersionIdentifiers) Reset() { *m = EndDeviceVersionIdentifiers{} } func (*EndDeviceVersionIdentifiers) ProtoMessage() {} func (*EndDeviceVersionIdentifiers) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{4} + return fileDescriptor_end_device_1fd831da224133be, []int{4} } func (m *EndDeviceVersionIdentifiers) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -683,7 +683,7 @@ type EndDeviceVersion struct { func (m *EndDeviceVersion) Reset() { *m = EndDeviceVersion{} } func (*EndDeviceVersion) ProtoMessage() {} func (*EndDeviceVersion) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{5} + return fileDescriptor_end_device_1fd831da224133be, []int{5} } func (m *EndDeviceVersion) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -811,18 +811,18 @@ func (m *EndDeviceVersion) GetDefaultFormatters() MessagePayloadFormatters { } type MACSettings struct { - UseADR bool `protobuf:"varint,1,opt,name=use_adr,json=useAdr,proto3" json:"use_adr,omitempty"` + UseADR *types.BoolValue `protobuf:"bytes,1,opt,name=use_adr,json=useAdr,proto3" json:"use_adr,omitempty"` // The ADR margin tells the network server how much margin it should add in ADR requests. // A bigger margin is less efficient, but gives a better chance of successful reception. - ADRMargin uint32 `protobuf:"varint,2,opt,name=adr_margin,json=adrMargin,proto3" json:"adr_margin,omitempty"` + ADRMargin *types.UInt32Value `protobuf:"bytes,2,opt,name=adr_margin,json=adrMargin,proto3" json:"adr_margin,omitempty"` // Deadline for the device to respond to requests from the Network Server. - ClassBTimeout time.Duration `protobuf:"bytes,3,opt,name=class_b_timeout,json=classBTimeout,proto3,stdduration" json:"class_b_timeout"` + ClassBTimeout *time.Duration `protobuf:"bytes,3,opt,name=class_b_timeout,json=classBTimeout,proto3,stdduration" json:"class_b_timeout,omitempty"` // Deadline for the device to respond to requests from the Network Server. - ClassCTimeout time.Duration `protobuf:"bytes,4,opt,name=class_c_timeout,json=classCTimeout,proto3,stdduration" json:"class_c_timeout"` + ClassCTimeout *time.Duration `protobuf:"bytes,4,opt,name=class_c_timeout,json=classCTimeout,proto3,stdduration" json:"class_c_timeout,omitempty"` // The interval after which a DevStatusReq MACCommand shall be sent. - StatusTimePeriodicity time.Duration `protobuf:"bytes,5,opt,name=status_time_periodicity,json=statusTimePeriodicity,proto3,stdduration" json:"status_time_periodicity"` + StatusTimePeriodicity *time.Duration `protobuf:"bytes,5,opt,name=status_time_periodicity,json=statusTimePeriodicity,proto3,stdduration" json:"status_time_periodicity,omitempty"` // Number of uplink messages after which a DevStatusReq MACCommand shall be sent. - StatusCountPeriodicity uint32 `protobuf:"varint,6,opt,name=status_count_periodicity,json=statusCountPeriodicity,proto3" json:"status_count_periodicity,omitempty"` + StatusCountPeriodicity *types.UInt32Value `protobuf:"bytes,6,opt,name=status_count_periodicity,json=statusCountPeriodicity,proto3" json:"status_count_periodicity,omitempty"` Rx1Delay *MACSettings_RxDelayValue `protobuf:"bytes,7,opt,name=rx1_delay,json=rx1Delay,proto3" json:"rx1_delay,omitempty"` Rx2DataRateIndex *MACSettings_DataRateIndexValue `protobuf:"bytes,8,opt,name=rx2_data_rate_index,json=rx2DataRateIndex,proto3" json:"rx2_data_rate_index,omitempty"` Rx2Frequency *types.UInt64Value `protobuf:"bytes,9,opt,name=rx2_frequency,json=rx2Frequency,proto3" json:"rx2_frequency,omitempty"` @@ -833,7 +833,7 @@ type MACSettings struct { func (m *MACSettings) Reset() { *m = MACSettings{} } func (*MACSettings) ProtoMessage() {} func (*MACSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{6} + return fileDescriptor_end_device_1fd831da224133be, []int{6} } func (m *MACSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -862,46 +862,46 @@ func (m *MACSettings) XXX_DiscardUnknown() { var xxx_messageInfo_MACSettings proto.InternalMessageInfo -func (m *MACSettings) GetUseADR() bool { +func (m *MACSettings) GetUseADR() *types.BoolValue { if m != nil { return m.UseADR } - return false + return nil } -func (m *MACSettings) GetADRMargin() uint32 { +func (m *MACSettings) GetADRMargin() *types.UInt32Value { if m != nil { return m.ADRMargin } - return 0 + return nil } -func (m *MACSettings) GetClassBTimeout() time.Duration { +func (m *MACSettings) GetClassBTimeout() *time.Duration { if m != nil { return m.ClassBTimeout } - return 0 + return nil } -func (m *MACSettings) GetClassCTimeout() time.Duration { +func (m *MACSettings) GetClassCTimeout() *time.Duration { if m != nil { return m.ClassCTimeout } - return 0 + return nil } -func (m *MACSettings) GetStatusTimePeriodicity() time.Duration { +func (m *MACSettings) GetStatusTimePeriodicity() *time.Duration { if m != nil { return m.StatusTimePeriodicity } - return 0 + return nil } -func (m *MACSettings) GetStatusCountPeriodicity() uint32 { +func (m *MACSettings) GetStatusCountPeriodicity() *types.UInt32Value { if m != nil { return m.StatusCountPeriodicity } - return 0 + return nil } func (m *MACSettings) GetRx1Delay() *MACSettings_RxDelayValue { @@ -934,7 +934,7 @@ type MACSettings_RxDelayValue struct { func (m *MACSettings_RxDelayValue) Reset() { *m = MACSettings_RxDelayValue{} } func (*MACSettings_RxDelayValue) ProtoMessage() {} func (*MACSettings_RxDelayValue) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{6, 0} + return fileDescriptor_end_device_1fd831da224133be, []int{6, 0} } func (m *MACSettings_RxDelayValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -979,7 +979,7 @@ type MACSettings_DataRateIndexValue struct { func (m *MACSettings_DataRateIndexValue) Reset() { *m = MACSettings_DataRateIndexValue{} } func (*MACSettings_DataRateIndexValue) ProtoMessage() {} func (*MACSettings_DataRateIndexValue) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{6, 1} + return fileDescriptor_end_device_1fd831da224133be, []int{6, 1} } func (m *MACSettings_DataRateIndexValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1061,7 +1061,7 @@ type MACState struct { func (m *MACState) Reset() { *m = MACState{} } func (*MACState) ProtoMessage() {} func (*MACState) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{7} + return fileDescriptor_end_device_1fd831da224133be, []int{7} } func (m *MACState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1195,7 +1195,7 @@ type MACState_JoinAccept struct { func (m *MACState_JoinAccept) Reset() { *m = MACState_JoinAccept{} } func (*MACState_JoinAccept) ProtoMessage() {} func (*MACState_JoinAccept) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{7, 0} + return fileDescriptor_end_device_1fd831da224133be, []int{7, 0} } func (m *MACState_JoinAccept) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1392,7 +1392,7 @@ type EndDevice struct { func (m *EndDevice) Reset() { *m = EndDevice{} } func (*EndDevice) ProtoMessage() {} func (*EndDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{8} + return fileDescriptor_end_device_1fd831da224133be, []int{8} } func (m *EndDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1738,7 +1738,7 @@ type EndDevices struct { func (m *EndDevices) Reset() { *m = EndDevices{} } func (*EndDevices) ProtoMessage() {} func (*EndDevices) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{9} + return fileDescriptor_end_device_1fd831da224133be, []int{9} } func (m *EndDevices) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1783,7 +1783,7 @@ type CreateEndDeviceRequest struct { func (m *CreateEndDeviceRequest) Reset() { *m = CreateEndDeviceRequest{} } func (*CreateEndDeviceRequest) ProtoMessage() {} func (*CreateEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{10} + return fileDescriptor_end_device_1fd831da224133be, []int{10} } func (m *CreateEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1822,7 +1822,7 @@ type UpdateEndDeviceRequest struct { func (m *UpdateEndDeviceRequest) Reset() { *m = UpdateEndDeviceRequest{} } func (*UpdateEndDeviceRequest) ProtoMessage() {} func (*UpdateEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{11} + return fileDescriptor_end_device_1fd831da224133be, []int{11} } func (m *UpdateEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1868,7 +1868,7 @@ type GetEndDeviceRequest struct { func (m *GetEndDeviceRequest) Reset() { *m = GetEndDeviceRequest{} } func (*GetEndDeviceRequest) ProtoMessage() {} func (*GetEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{12} + return fileDescriptor_end_device_1fd831da224133be, []int{12} } func (m *GetEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1921,7 +1921,7 @@ type ListEndDevicesRequest struct { func (m *ListEndDevicesRequest) Reset() { *m = ListEndDevicesRequest{} } func (*ListEndDevicesRequest) ProtoMessage() {} func (*ListEndDevicesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{13} + return fileDescriptor_end_device_1fd831da224133be, []int{13} } func (m *ListEndDevicesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1988,7 +1988,7 @@ type SetEndDeviceRequest struct { func (m *SetEndDeviceRequest) Reset() { *m = SetEndDeviceRequest{} } func (*SetEndDeviceRequest) ProtoMessage() {} func (*SetEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_cd134bac00aa082e, []int{14} + return fileDescriptor_end_device_1fd831da224133be, []int{14} } func (m *SetEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2436,22 +2436,40 @@ func (this *MACSettings) Equal(that interface{}) bool { } else if this == nil { return false } - if this.UseADR != that1.UseADR { + if !this.UseADR.Equal(that1.UseADR) { return false } - if this.ADRMargin != that1.ADRMargin { + if !this.ADRMargin.Equal(that1.ADRMargin) { return false } - if this.ClassBTimeout != that1.ClassBTimeout { + if this.ClassBTimeout != nil && that1.ClassBTimeout != nil { + if *this.ClassBTimeout != *that1.ClassBTimeout { + return false + } + } else if this.ClassBTimeout != nil { + return false + } else if that1.ClassBTimeout != nil { return false } - if this.ClassCTimeout != that1.ClassCTimeout { + if this.ClassCTimeout != nil && that1.ClassCTimeout != nil { + if *this.ClassCTimeout != *that1.ClassCTimeout { + return false + } + } else if this.ClassCTimeout != nil { + return false + } else if that1.ClassCTimeout != nil { return false } - if this.StatusTimePeriodicity != that1.StatusTimePeriodicity { + if this.StatusTimePeriodicity != nil && that1.StatusTimePeriodicity != nil { + if *this.StatusTimePeriodicity != *that1.StatusTimePeriodicity { + return false + } + } else if this.StatusTimePeriodicity != nil { + return false + } else if that1.StatusTimePeriodicity != nil { return false } - if this.StatusCountPeriodicity != that1.StatusCountPeriodicity { + if !this.StatusCountPeriodicity.Equal(that1.StatusCountPeriodicity) { return false } if !this.Rx1Delay.Equal(that1.Rx1Delay) { @@ -3527,79 +3545,95 @@ func (m *MACSettings) MarshalTo(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.UseADR { - dAtA[i] = 0x8 + if m.UseADR != nil { + dAtA[i] = 0xa i++ - if m.UseADR { - dAtA[i] = 1 - } else { - dAtA[i] = 0 + i = encodeVarintEndDevice(dAtA, i, uint64(m.UseADR.Size())) + n7, err := m.UseADR.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err } - i++ + i += n7 } - if m.ADRMargin != 0 { - dAtA[i] = 0x10 + if m.ADRMargin != nil { + dAtA[i] = 0x12 i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.ADRMargin)) + i = encodeVarintEndDevice(dAtA, i, uint64(m.ADRMargin.Size())) + n8, err := m.ADRMargin.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n8 } - dAtA[i] = 0x1a - i++ - i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(m.ClassBTimeout))) - n7, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.ClassBTimeout, dAtA[i:]) - if err != nil { - return 0, err + if m.ClassBTimeout != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ClassBTimeout))) + n9, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.ClassBTimeout, dAtA[i:]) + if err != nil { + return 0, err + } + i += n9 } - i += n7 - dAtA[i] = 0x22 - i++ - i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(m.ClassCTimeout))) - n8, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.ClassCTimeout, dAtA[i:]) - if err != nil { - return 0, err + if m.ClassCTimeout != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ClassCTimeout))) + n10, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.ClassCTimeout, dAtA[i:]) + if err != nil { + return 0, err + } + i += n10 } - i += n8 - dAtA[i] = 0x2a - i++ - i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(m.StatusTimePeriodicity))) - n9, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.StatusTimePeriodicity, dAtA[i:]) - if err != nil { - return 0, err + if m.StatusTimePeriodicity != nil { + dAtA[i] = 0x2a + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(*m.StatusTimePeriodicity))) + n11, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.StatusTimePeriodicity, dAtA[i:]) + if err != nil { + return 0, err + } + i += n11 } - i += n9 - if m.StatusCountPeriodicity != 0 { - dAtA[i] = 0x30 + if m.StatusCountPeriodicity != nil { + dAtA[i] = 0x32 i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.StatusCountPeriodicity)) + i = encodeVarintEndDevice(dAtA, i, uint64(m.StatusCountPeriodicity.Size())) + n12, err := m.StatusCountPeriodicity.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n12 } if m.Rx1Delay != nil { dAtA[i] = 0x3a i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Rx1Delay.Size())) - n10, err := m.Rx1Delay.MarshalTo(dAtA[i:]) + n13, err := m.Rx1Delay.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n10 + i += n13 } if m.Rx2DataRateIndex != nil { dAtA[i] = 0x42 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Rx2DataRateIndex.Size())) - n11, err := m.Rx2DataRateIndex.MarshalTo(dAtA[i:]) + n14, err := m.Rx2DataRateIndex.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n11 + i += n14 } if m.Rx2Frequency != nil { dAtA[i] = 0x4a i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Rx2Frequency.Size())) - n12, err := m.Rx2Frequency.MarshalTo(dAtA[i:]) + n15, err := m.Rx2Frequency.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n12 + i += n15 } return i, nil } @@ -3668,19 +3702,19 @@ func (m *MACState) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.CurrentParameters.Size())) - n13, err := m.CurrentParameters.MarshalTo(dAtA[i:]) + n16, err := m.CurrentParameters.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n13 + i += n16 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.DesiredParameters.Size())) - n14, err := m.DesiredParameters.MarshalTo(dAtA[i:]) + n17, err := m.DesiredParameters.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n14 + i += n17 if m.DeviceClass != 0 { dAtA[i] = 0x18 i++ @@ -3695,11 +3729,11 @@ func (m *MACState) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastConfirmedDownlinkAt))) - n15, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastConfirmedDownlinkAt, dAtA[i:]) + n18, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastConfirmedDownlinkAt, dAtA[i:]) if err != nil { return 0, err } - i += n15 + i += n18 } if m.LastDevStatusFCntUp != 0 { dAtA[i] = 0x30 @@ -3715,11 +3749,11 @@ func (m *MACState) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x42 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.PendingApplicationDownlink.Size())) - n16, err := m.PendingApplicationDownlink.MarshalTo(dAtA[i:]) + n19, err := m.PendingApplicationDownlink.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n16 + i += n19 } if len(m.QueuedResponses) > 0 { for _, msg := range m.QueuedResponses { @@ -3749,21 +3783,21 @@ func (m *MACState) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x5a i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.QueuedJoinAccept.Size())) - n17, err := m.QueuedJoinAccept.MarshalTo(dAtA[i:]) + n20, err := m.QueuedJoinAccept.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n17 + i += n20 } if m.PendingJoinRequest != nil { dAtA[i] = 0x62 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.PendingJoinRequest.Size())) - n18, err := m.PendingJoinRequest.MarshalTo(dAtA[i:]) + n21, err := m.PendingJoinRequest.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n18 + i += n21 } if m.RxWindowsAvailable { dAtA[i] = 0x68 @@ -3802,19 +3836,19 @@ func (m *MACState_JoinAccept) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Request.Size())) - n19, err := m.Request.MarshalTo(dAtA[i:]) + n22, err := m.Request.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n22 dAtA[i] = 0x1a i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Keys.Size())) - n20, err := m.Keys.MarshalTo(dAtA[i:]) + n23, err := m.Keys.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n23 return i, nil } @@ -3836,27 +3870,27 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.EndDeviceIdentifiers.Size())) - n21, err := m.EndDeviceIdentifiers.MarshalTo(dAtA[i:]) + n24, err := m.EndDeviceIdentifiers.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n24 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt))) - n22, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i:]) + n25, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i:]) if err != nil { return 0, err } - i += n22 + i += n25 dAtA[i] = 0x1a i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.UpdatedAt))) - n23, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.UpdatedAt, dAtA[i:]) + n26, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.UpdatedAt, dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n26 if len(m.Name) > 0 { dAtA[i] = 0x22 i++ @@ -3890,11 +3924,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x3a i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.VersionIDs.Size())) - n24, err := m.VersionIDs.MarshalTo(dAtA[i:]) + n27, err := m.VersionIDs.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n27 } if len(m.ServiceProfileID) > 0 { dAtA[i] = 0x42 @@ -3940,11 +3974,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(v.Size())) - n25, err := v.MarshalTo(dAtA[i:]) + n28, err := v.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n28 } } } @@ -3994,11 +4028,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.DefaultMACParameters.Size())) - n26, err := m.DefaultMACParameters.MarshalTo(dAtA[i:]) + n29, err := m.DefaultMACParameters.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n29 } if m.MinFrequency != 0 { dAtA[i] = 0x98 @@ -4068,11 +4102,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.RootKeys.Size())) - n27, err := m.RootKeys.MarshalTo(dAtA[i:]) + n30, err := m.RootKeys.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n27 + i += n30 } if m.NetID != nil { dAtA[i] = 0xd2 @@ -4080,11 +4114,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.NetID.Size())) - n28, err := m.NetID.MarshalTo(dAtA[i:]) + n31, err := m.NetID.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n28 + i += n31 } if m.MACSettings != nil { dAtA[i] = 0xda @@ -4092,11 +4126,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.MACSettings.Size())) - n29, err := m.MACSettings.MarshalTo(dAtA[i:]) + n32, err := m.MACSettings.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n29 + i += n32 } if m.MACState != nil { dAtA[i] = 0xe2 @@ -4104,11 +4138,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.MACState.Size())) - n30, err := m.MACState.MarshalTo(dAtA[i:]) + n33, err := m.MACState.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n30 + i += n33 } if m.Session != nil { dAtA[i] = 0xea @@ -4116,11 +4150,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Session.Size())) - n31, err := m.Session.MarshalTo(dAtA[i:]) + n34, err := m.Session.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n31 + i += n34 } if m.PendingSession != nil { dAtA[i] = 0xf2 @@ -4128,11 +4162,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.PendingSession.Size())) - n32, err := m.PendingSession.MarshalTo(dAtA[i:]) + n35, err := m.PendingSession.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n32 + i += n35 } if m.LastDevNonce != 0 { dAtA[i] = 0xf8 @@ -4142,23 +4176,23 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintEndDevice(dAtA, i, uint64(m.LastDevNonce)) } if len(m.UsedDevNonces) > 0 { - dAtA34 := make([]byte, len(m.UsedDevNonces)*10) - var j33 int + dAtA37 := make([]byte, len(m.UsedDevNonces)*10) + var j36 int for _, num := range m.UsedDevNonces { for num >= 1<<7 { - dAtA34[j33] = uint8(uint64(num)&0x7f | 0x80) + dAtA37[j36] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j33++ + j36++ } - dAtA34[j33] = uint8(num) - j33++ + dAtA37[j36] = uint8(num) + j36++ } dAtA[i] = 0x82 i++ dAtA[i] = 0x2 i++ - i = encodeVarintEndDevice(dAtA, i, uint64(j33)) - i += copy(dAtA[i:], dAtA34[:j33]) + i = encodeVarintEndDevice(dAtA, i, uint64(j36)) + i += copy(dAtA[i:], dAtA37[:j36]) } if m.LastJoinNonce != 0 { dAtA[i] = 0x88 @@ -4187,11 +4221,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2 i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastDevStatusReceivedAt))) - n35, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastDevStatusReceivedAt, dAtA[i:]) + n38, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastDevStatusReceivedAt, dAtA[i:]) if err != nil { return 0, err } - i += n35 + i += n38 } if m.PowerState != 0 { dAtA[i] = 0xa8 @@ -4277,11 +4311,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Formatters.Size())) - n36, err := m.Formatters.MarshalTo(dAtA[i:]) + n39, err := m.Formatters.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n36 + i += n39 } if len(m.ProvisionerID) > 0 { dAtA[i] = 0xea @@ -4297,11 +4331,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.ProvisioningData.Size())) - n37, err := m.ProvisioningData.MarshalTo(dAtA[i:]) + n40, err := m.ProvisioningData.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n37 + i += n40 } return i, nil } @@ -4354,11 +4388,11 @@ func (m *CreateEndDeviceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.EndDevice.Size())) - n38, err := m.EndDevice.MarshalTo(dAtA[i:]) + n41, err := m.EndDevice.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n38 + i += n41 return i, nil } @@ -4380,19 +4414,19 @@ func (m *UpdateEndDeviceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.EndDevice.Size())) - n39, err := m.EndDevice.MarshalTo(dAtA[i:]) + n42, err := m.EndDevice.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n39 + i += n42 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.FieldMask.Size())) - n40, err := m.FieldMask.MarshalTo(dAtA[i:]) + n43, err := m.FieldMask.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n40 + i += n43 return i, nil } @@ -4414,19 +4448,19 @@ func (m *GetEndDeviceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.EndDeviceIdentifiers.Size())) - n41, err := m.EndDeviceIdentifiers.MarshalTo(dAtA[i:]) + n44, err := m.EndDeviceIdentifiers.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n41 + i += n44 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.FieldMask.Size())) - n42, err := m.FieldMask.MarshalTo(dAtA[i:]) + n45, err := m.FieldMask.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n42 + i += n45 return i, nil } @@ -4448,19 +4482,19 @@ func (m *ListEndDevicesRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.ApplicationIdentifiers.Size())) - n43, err := m.ApplicationIdentifiers.MarshalTo(dAtA[i:]) + n46, err := m.ApplicationIdentifiers.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n43 + i += n46 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.FieldMask.Size())) - n44, err := m.FieldMask.MarshalTo(dAtA[i:]) + n47, err := m.FieldMask.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n44 + i += n47 if len(m.Order) > 0 { dAtA[i] = 0x1a i++ @@ -4498,19 +4532,19 @@ func (m *SetEndDeviceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Device.Size())) - n45, err := m.Device.MarshalTo(dAtA[i:]) + n48, err := m.Device.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n45 + i += n48 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.FieldMask.Size())) - n46, err := m.FieldMask.MarshalTo(dAtA[i:]) + n49, err := m.FieldMask.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n46 + i += n49 return i, nil } @@ -4578,15 +4612,24 @@ func NewPopulatedEndDeviceVersionIdentifiers(r randyEndDevice, easy bool) *EndDe func NewPopulatedMACSettings(r randyEndDevice, easy bool) *MACSettings { this := &MACSettings{} - this.UseADR = bool(r.Intn(2) == 0) - this.ADRMargin = r.Uint32() - v5 := github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy) - this.ClassBTimeout = *v5 - v6 := github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy) - this.ClassCTimeout = *v6 - v7 := github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy) - this.StatusTimePeriodicity = *v7 - this.StatusCountPeriodicity = r.Uint32() + if r.Intn(10) != 0 { + this.UseADR = types.NewPopulatedBoolValue(r, easy) + } + if r.Intn(10) != 0 { + this.ADRMargin = types.NewPopulatedUInt32Value(r, easy) + } + if r.Intn(10) != 0 { + this.ClassBTimeout = github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy) + } + if r.Intn(10) != 0 { + this.ClassCTimeout = github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy) + } + if r.Intn(10) != 0 { + this.StatusTimePeriodicity = github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy) + } + if r.Intn(10) != 0 { + this.StatusCountPeriodicity = types.NewPopulatedUInt32Value(r, easy) + } if r.Intn(10) != 0 { this.Rx1Delay = NewPopulatedMACSettings_RxDelayValue(r, easy) } @@ -4619,15 +4662,15 @@ func NewPopulatedMACSettings_DataRateIndexValue(r randyEndDevice, easy bool) *MA func NewPopulatedMACState_JoinAccept(r randyEndDevice, easy bool) *MACState_JoinAccept { this := &MACState_JoinAccept{} - v8 := r.Intn(100) - this.Payload = make([]byte, v8) - for i := 0; i < v8; i++ { + v5 := r.Intn(100) + this.Payload = make([]byte, v5) + for i := 0; i < v5; i++ { this.Payload[i] = byte(r.Intn(256)) } - v9 := NewPopulatedJoinRequest(r, easy) - this.Request = *v9 - v10 := NewPopulatedSessionKeys(r, easy) - this.Keys = *v10 + v6 := NewPopulatedJoinRequest(r, easy) + this.Request = *v6 + v7 := NewPopulatedSessionKeys(r, easy) + this.Keys = *v7 if !easy && r.Intn(10) != 0 { } return this @@ -4636,9 +4679,9 @@ func NewPopulatedMACState_JoinAccept(r randyEndDevice, easy bool) *MACState_Join func NewPopulatedEndDevices(r randyEndDevice, easy bool) *EndDevices { this := &EndDevices{} if r.Intn(10) != 0 { - v11 := r.Intn(5) - this.EndDevices = make([]*EndDevice, v11) - for i := 0; i < v11; i++ { + v8 := r.Intn(5) + this.EndDevices = make([]*EndDevice, v8) + for i := 0; i < v8; i++ { this.EndDevices[i] = NewPopulatedEndDevice(r, easy) } } @@ -4649,8 +4692,8 @@ func NewPopulatedEndDevices(r randyEndDevice, easy bool) *EndDevices { func NewPopulatedCreateEndDeviceRequest(r randyEndDevice, easy bool) *CreateEndDeviceRequest { this := &CreateEndDeviceRequest{} - v12 := NewPopulatedEndDevice(r, easy) - this.EndDevice = *v12 + v9 := NewPopulatedEndDevice(r, easy) + this.EndDevice = *v9 if !easy && r.Intn(10) != 0 { } return this @@ -4658,10 +4701,10 @@ func NewPopulatedCreateEndDeviceRequest(r randyEndDevice, easy bool) *CreateEndD func NewPopulatedUpdateEndDeviceRequest(r randyEndDevice, easy bool) *UpdateEndDeviceRequest { this := &UpdateEndDeviceRequest{} - v13 := NewPopulatedEndDevice(r, easy) - this.EndDevice = *v13 - v14 := types.NewPopulatedFieldMask(r, easy) - this.FieldMask = *v14 + v10 := NewPopulatedEndDevice(r, easy) + this.EndDevice = *v10 + v11 := types.NewPopulatedFieldMask(r, easy) + this.FieldMask = *v11 if !easy && r.Intn(10) != 0 { } return this @@ -4669,10 +4712,10 @@ func NewPopulatedUpdateEndDeviceRequest(r randyEndDevice, easy bool) *UpdateEndD func NewPopulatedGetEndDeviceRequest(r randyEndDevice, easy bool) *GetEndDeviceRequest { this := &GetEndDeviceRequest{} - v15 := NewPopulatedEndDeviceIdentifiers(r, easy) - this.EndDeviceIdentifiers = *v15 - v16 := types.NewPopulatedFieldMask(r, easy) - this.FieldMask = *v16 + v12 := NewPopulatedEndDeviceIdentifiers(r, easy) + this.EndDeviceIdentifiers = *v12 + v13 := types.NewPopulatedFieldMask(r, easy) + this.FieldMask = *v13 if !easy && r.Intn(10) != 0 { } return this @@ -4680,10 +4723,10 @@ func NewPopulatedGetEndDeviceRequest(r randyEndDevice, easy bool) *GetEndDeviceR func NewPopulatedListEndDevicesRequest(r randyEndDevice, easy bool) *ListEndDevicesRequest { this := &ListEndDevicesRequest{} - v17 := NewPopulatedApplicationIdentifiers(r, easy) - this.ApplicationIdentifiers = *v17 - v18 := types.NewPopulatedFieldMask(r, easy) - this.FieldMask = *v18 + v14 := NewPopulatedApplicationIdentifiers(r, easy) + this.ApplicationIdentifiers = *v14 + v15 := types.NewPopulatedFieldMask(r, easy) + this.FieldMask = *v15 this.Order = randStringEndDevice(r) this.Limit = r.Uint32() this.Page = r.Uint32() @@ -4694,10 +4737,10 @@ func NewPopulatedListEndDevicesRequest(r randyEndDevice, easy bool) *ListEndDevi func NewPopulatedSetEndDeviceRequest(r randyEndDevice, easy bool) *SetEndDeviceRequest { this := &SetEndDeviceRequest{} - v19 := NewPopulatedEndDevice(r, easy) - this.Device = *v19 - v20 := types.NewPopulatedFieldMask(r, easy) - this.FieldMask = *v20 + v16 := NewPopulatedEndDevice(r, easy) + this.Device = *v16 + v17 := types.NewPopulatedFieldMask(r, easy) + this.FieldMask = *v17 if !easy && r.Intn(10) != 0 { } return this @@ -4722,9 +4765,9 @@ func randUTF8RuneEndDevice(r randyEndDevice) rune { return rune(ru + 61) } func randStringEndDevice(r randyEndDevice) string { - v21 := r.Intn(100) - tmps := make([]rune, v21) - for i := 0; i < v21; i++ { + v18 := r.Intn(100) + tmps := make([]rune, v18) + for i := 0; i < v18; i++ { tmps[i] = randUTF8RuneEndDevice(r) } return string(tmps) @@ -4746,11 +4789,11 @@ func randFieldEndDevice(dAtA []byte, r randyEndDevice, fieldNumber int, wire int switch wire { case 0: dAtA = encodeVarintPopulateEndDevice(dAtA, uint64(key)) - v22 := r.Int63() + v19 := r.Int63() if r.Intn(2) == 0 { - v22 *= -1 + v19 *= -1 } - dAtA = encodeVarintPopulateEndDevice(dAtA, uint64(v22)) + dAtA = encodeVarintPopulateEndDevice(dAtA, uint64(v19)) case 1: dAtA = encodeVarintPopulateEndDevice(dAtA, uint64(key)) dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) @@ -5031,20 +5074,29 @@ func (m *MACSettings) Size() (n int) { } var l int _ = l - if m.UseADR { - n += 2 + if m.UseADR != nil { + l = m.UseADR.Size() + n += 1 + l + sovEndDevice(uint64(l)) } - if m.ADRMargin != 0 { - n += 1 + sovEndDevice(uint64(m.ADRMargin)) + if m.ADRMargin != nil { + l = m.ADRMargin.Size() + n += 1 + l + sovEndDevice(uint64(l)) } - l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.ClassBTimeout) - n += 1 + l + sovEndDevice(uint64(l)) - l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.ClassCTimeout) - n += 1 + l + sovEndDevice(uint64(l)) - l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.StatusTimePeriodicity) - n += 1 + l + sovEndDevice(uint64(l)) - if m.StatusCountPeriodicity != 0 { - n += 1 + sovEndDevice(uint64(m.StatusCountPeriodicity)) + if m.ClassBTimeout != nil { + l = github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ClassBTimeout) + n += 1 + l + sovEndDevice(uint64(l)) + } + if m.ClassCTimeout != nil { + l = github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ClassCTimeout) + n += 1 + l + sovEndDevice(uint64(l)) + } + if m.StatusTimePeriodicity != nil { + l = github_com_gogo_protobuf_types.SizeOfStdDuration(*m.StatusTimePeriodicity) + n += 1 + l + sovEndDevice(uint64(l)) + } + if m.StatusCountPeriodicity != nil { + l = m.StatusCountPeriodicity.Size() + n += 1 + l + sovEndDevice(uint64(l)) } if m.Rx1Delay != nil { l = m.Rx1Delay.Size() @@ -5578,12 +5630,12 @@ func (this *MACSettings) String() string { return "nil" } s := strings.Join([]string{`&MACSettings{`, - `UseADR:` + fmt.Sprintf("%v", this.UseADR) + `,`, - `ADRMargin:` + fmt.Sprintf("%v", this.ADRMargin) + `,`, - `ClassBTimeout:` + strings.Replace(strings.Replace(this.ClassBTimeout.String(), "Duration", "types.Duration", 1), `&`, ``, 1) + `,`, - `ClassCTimeout:` + strings.Replace(strings.Replace(this.ClassCTimeout.String(), "Duration", "types.Duration", 1), `&`, ``, 1) + `,`, - `StatusTimePeriodicity:` + strings.Replace(strings.Replace(this.StatusTimePeriodicity.String(), "Duration", "types.Duration", 1), `&`, ``, 1) + `,`, - `StatusCountPeriodicity:` + fmt.Sprintf("%v", this.StatusCountPeriodicity) + `,`, + `UseADR:` + strings.Replace(fmt.Sprintf("%v", this.UseADR), "BoolValue", "types.BoolValue", 1) + `,`, + `ADRMargin:` + strings.Replace(fmt.Sprintf("%v", this.ADRMargin), "UInt32Value", "types.UInt32Value", 1) + `,`, + `ClassBTimeout:` + strings.Replace(fmt.Sprintf("%v", this.ClassBTimeout), "Duration", "types.Duration", 1) + `,`, + `ClassCTimeout:` + strings.Replace(fmt.Sprintf("%v", this.ClassCTimeout), "Duration", "types.Duration", 1) + `,`, + `StatusTimePeriodicity:` + strings.Replace(fmt.Sprintf("%v", this.StatusTimePeriodicity), "Duration", "types.Duration", 1) + `,`, + `StatusCountPeriodicity:` + strings.Replace(fmt.Sprintf("%v", this.StatusCountPeriodicity), "UInt32Value", "types.UInt32Value", 1) + `,`, `Rx1Delay:` + strings.Replace(fmt.Sprintf("%v", this.Rx1Delay), "MACSettings_RxDelayValue", "MACSettings_RxDelayValue", 1) + `,`, `Rx2DataRateIndex:` + strings.Replace(fmt.Sprintf("%v", this.Rx2DataRateIndex), "MACSettings_DataRateIndexValue", "MACSettings_DataRateIndexValue", 1) + `,`, `Rx2Frequency:` + strings.Replace(fmt.Sprintf("%v", this.Rx2Frequency), "UInt64Value", "types.UInt64Value", 1) + `,`, @@ -7470,10 +7522,10 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field UseADR", wireType) } - var v int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEndDevice @@ -7483,17 +7535,30 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= (int(b) & 0x7F) << shift + msglen |= (int(b) & 0x7F) << shift if b < 0x80 { break } } - m.UseADR = bool(v != 0) + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.UseADR == nil { + m.UseADR = &types.BoolValue{} + } + if err := m.UseADR.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 2: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ADRMargin", wireType) } - m.ADRMargin = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEndDevice @@ -7503,11 +7568,25 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ADRMargin |= (uint32(b) & 0x7F) << shift + msglen |= (int(b) & 0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ADRMargin == nil { + m.ADRMargin = &types.UInt32Value{} + } + if err := m.ADRMargin.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ClassBTimeout", wireType) @@ -7534,7 +7613,10 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.ClassBTimeout, dAtA[iNdEx:postIndex]); err != nil { + if m.ClassBTimeout == nil { + m.ClassBTimeout = new(time.Duration) + } + if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(m.ClassBTimeout, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -7564,7 +7646,10 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.ClassCTimeout, dAtA[iNdEx:postIndex]); err != nil { + if m.ClassCTimeout == nil { + m.ClassCTimeout = new(time.Duration) + } + if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(m.ClassCTimeout, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -7594,15 +7679,18 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.StatusTimePeriodicity, dAtA[iNdEx:postIndex]); err != nil { + if m.StatusTimePeriodicity == nil { + m.StatusTimePeriodicity = new(time.Duration) + } + if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(m.StatusTimePeriodicity, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 6: - if wireType != 0 { + if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field StatusCountPeriodicity", wireType) } - m.StatusCountPeriodicity = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEndDevice @@ -7612,11 +7700,25 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.StatusCountPeriodicity |= (uint32(b) & 0x7F) << shift + msglen |= (int(b) & 0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.StatusCountPeriodicity == nil { + m.StatusCountPeriodicity = &types.UInt32Value{} + } + if err := m.StatusCountPeriodicity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Rx1Delay", wireType) @@ -10683,233 +10785,234 @@ var ( ) func init() { - proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_cd134bac00aa082e) + proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_1fd831da224133be) } func init() { - golang_proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_cd134bac00aa082e) -} - -var fileDescriptor_end_device_cd134bac00aa082e = []byte{ - // 3529 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5a, 0x4b, 0x70, 0x1b, 0xc7, - 0x99, 0xc6, 0x80, 0x14, 0x09, 0x34, 0xde, 0x4d, 0x4a, 0x1a, 0xd3, 0x32, 0x40, 0x53, 0xb2, 0x43, - 0x3b, 0x22, 0x28, 0x51, 0x72, 0xe2, 0x28, 0x49, 0xc9, 0x00, 0x41, 0xc5, 0xb4, 0x29, 0x8a, 0xdb, - 0x92, 0xac, 0x75, 0x1c, 0x79, 0xaa, 0x89, 0x69, 0x82, 0x63, 0x02, 0x33, 0x93, 0xee, 0x06, 0x09, - 0xee, 0xa3, 0x2a, 0x87, 0xdd, 0xaa, 0xdc, 0x92, 0xc3, 0x6e, 0x55, 0x2e, 0x5b, 0x95, 0xda, 0xda, - 0xad, 0x4a, 0x6d, 0xed, 0x21, 0x47, 0x1f, 0x73, 0xf4, 0xd1, 0xc7, 0x54, 0x0e, 0x70, 0x04, 0x5e, - 0x72, 0x4c, 0xd5, 0x5e, 0x7c, 0xdc, 0xea, 0xc7, 0x3c, 0xf0, 0x20, 0x4d, 0xda, 0xeb, 0xbd, 0xb0, - 0x66, 0xfe, 0xff, 0xfb, 0xbf, 0xf9, 0xfb, 0xf5, 0x3f, 0x1a, 0x04, 0x4b, 0x6d, 0x8f, 0xe2, 0x23, - 0xec, 0xae, 0x30, 0x8e, 0x9b, 0x07, 0xab, 0xd8, 0x77, 0x56, 0x89, 0x6b, 0x5b, 0x36, 0x39, 0x74, - 0x9a, 0xa4, 0xea, 0x53, 0x8f, 0x7b, 0x30, 0xcf, 0xb9, 0x5b, 0xd5, 0xb8, 0xea, 0xe1, 0x9d, 0x85, - 0x95, 0x96, 0xc3, 0xf7, 0xbb, 0xbb, 0xd5, 0xa6, 0xd7, 0x59, 0x6d, 0x79, 0x2d, 0x6f, 0x55, 0xc2, - 0x76, 0xbb, 0x7b, 0xf2, 0x4d, 0xbe, 0xc8, 0x27, 0x65, 0xbe, 0xf0, 0xbd, 0x18, 0xbc, 0x73, 0xe4, - 0xf0, 0x03, 0xef, 0x68, 0xb5, 0xe5, 0xad, 0x48, 0xe5, 0xca, 0x21, 0x6e, 0x3b, 0x36, 0xe6, 0x1e, - 0x65, 0xab, 0xe1, 0xa3, 0xb6, 0xbb, 0xd6, 0xf2, 0xbc, 0x56, 0x9b, 0x48, 0x9f, 0xb0, 0xeb, 0x7a, - 0x1c, 0x73, 0xc7, 0x73, 0x99, 0xd6, 0x96, 0xb5, 0x36, 0xfc, 0xb6, 0xdd, 0xa5, 0x12, 0xa0, 0xf5, - 0x8b, 0xa3, 0xfa, 0x3d, 0x87, 0xb4, 0x6d, 0xab, 0x83, 0xd9, 0xc1, 0x08, 0x7f, 0x88, 0x60, 0x9c, - 0x76, 0x9b, 0x5c, 0x6b, 0x2b, 0xa3, 0x5a, 0xee, 0x74, 0x08, 0xe3, 0xb8, 0xe3, 0x9f, 0xe6, 0xc0, - 0x11, 0xc5, 0xbe, 0x4f, 0x68, 0xe0, 0xe0, 0xf5, 0xf1, 0x99, 0x75, 0x6c, 0xe2, 0x72, 0x67, 0xcf, - 0x89, 0x40, 0xd7, 0xc6, 0x41, 0x9f, 0x78, 0x8e, 0x7b, 0xba, 0xf6, 0x80, 0x1c, 0x07, 0xb6, 0x95, - 0x71, 0x6d, 0xb0, 0x48, 0x7a, 0x0a, 0xc6, 0x01, 0x1d, 0xc2, 0x18, 0x6e, 0x11, 0x76, 0x16, 0x82, - 0x63, 0x1b, 0x73, 0xac, 0x10, 0x4b, 0xbf, 0x9a, 0x02, 0xb3, 0x8f, 0x09, 0x63, 0x8e, 0xe7, 0xc2, - 0x67, 0x20, 0x65, 0x93, 0x43, 0x0b, 0xdb, 0x36, 0x35, 0x93, 0x8b, 0xc6, 0x72, 0xb6, 0xfe, 0xa3, - 0xcf, 0xfa, 0x95, 0xc4, 0x9f, 0xfa, 0x95, 0xbb, 0x2d, 0xaf, 0xca, 0xf7, 0x09, 0xdf, 0x77, 0xdc, - 0x16, 0xab, 0xba, 0x84, 0x1f, 0x79, 0xf4, 0x60, 0x75, 0x98, 0xdc, 0x3f, 0x68, 0xad, 0xf2, 0x63, - 0x9f, 0xb0, 0x6a, 0x83, 0x1c, 0xd6, 0x6c, 0x9b, 0xa2, 0x59, 0x5b, 0x3d, 0xc0, 0x1f, 0x80, 0x69, - 0x31, 0x2e, 0x73, 0x6a, 0xd1, 0x58, 0xce, 0xac, 0xbd, 0x5c, 0x1d, 0xde, 0x6f, 0x55, 0xfd, 0xfd, - 0xf7, 0xc9, 0x31, 0xab, 0xa7, 0xc4, 0x17, 0x3f, 0xef, 0x57, 0x0c, 0x24, 0x4d, 0xe0, 0xab, 0x20, - 0xd7, 0xc6, 0x8c, 0x5b, 0x7b, 0x56, 0xd3, 0xe5, 0x56, 0xd7, 0x37, 0xa7, 0x17, 0x8d, 0xe5, 0x1c, - 0x02, 0x42, 0xf8, 0x60, 0xdd, 0xe5, 0x4f, 0x7d, 0xb8, 0x0c, 0x4a, 0x12, 0xe2, 0x6a, 0x90, 0xed, - 0x1d, 0xb9, 0xe6, 0x25, 0x09, 0x93, 0xb6, 0xdb, 0x02, 0xd7, 0xf0, 0x8e, 0xdc, 0x10, 0x89, 0xe3, - 0xc8, 0x99, 0x08, 0x59, 0x0b, 0x91, 0x55, 0x30, 0x2f, 0x91, 0x4d, 0xcf, 0xdd, 0x8b, 0x83, 0x67, - 0x25, 0xb8, 0x28, 0x74, 0xeb, 0x9e, 0xbb, 0x17, 0xe2, 0xd7, 0x01, 0x60, 0x1c, 0x53, 0x4e, 0x6c, - 0x0b, 0x73, 0x33, 0x25, 0xc7, 0xb9, 0x50, 0x55, 0x3b, 0xa8, 0x1a, 0xec, 0xa0, 0xea, 0x93, 0x60, - 0x8b, 0xa9, 0x61, 0xfe, 0xfa, 0x8b, 0x8a, 0x81, 0xd2, 0xda, 0xae, 0xc6, 0xdf, 0x9b, 0x4e, 0x19, - 0xc5, 0xe4, 0xd2, 0x17, 0x19, 0x90, 0x7b, 0x58, 0x5b, 0xdf, 0xc1, 0x14, 0x77, 0x08, 0x27, 0x94, - 0xc1, 0xd7, 0x41, 0xaa, 0x83, 0x7b, 0x16, 0x71, 0xa8, 0x6f, 0x1a, 0x8b, 0xc6, 0x72, 0xb2, 0x9e, - 0x19, 0xf4, 0x2b, 0xb3, 0x0f, 0x71, 0x6f, 0x63, 0x13, 0xed, 0xa0, 0xd9, 0x0e, 0xee, 0x6d, 0x38, - 0xd4, 0x87, 0x6f, 0x82, 0x52, 0xd7, 0x6f, 0x3b, 0xee, 0x81, 0x65, 0x1f, 0x91, 0x76, 0xdb, 0x12, - 0x3b, 0x5a, 0x2e, 0x64, 0x0a, 0x15, 0x94, 0xa2, 0x21, 0xe4, 0xc2, 0x0b, 0x58, 0x05, 0x73, 0x62, - 0x40, 0xa3, 0xe8, 0x29, 0x89, 0x2e, 0x05, 0xaa, 0x08, 0xbf, 0x0b, 0xe6, 0xb0, 0x4d, 0x2d, 0xb1, - 0x73, 0x2c, 0x8a, 0x39, 0xb1, 0x1c, 0xd7, 0x26, 0x3d, 0xb9, 0x1a, 0xf9, 0xb5, 0x57, 0x46, 0x57, - 0xb4, 0x81, 0x39, 0x46, 0x98, 0x93, 0x4d, 0x01, 0xaa, 0xcf, 0x0f, 0xfa, 0x95, 0x62, 0xad, 0x81, - 0x86, 0xa4, 0xa8, 0x88, 0x6d, 0x3a, 0x24, 0x81, 0xef, 0x00, 0x28, 0xbe, 0xc1, 0x7b, 0x96, 0xef, - 0x1d, 0x11, 0xaa, 0x3f, 0x21, 0x57, 0xb2, 0x3e, 0x37, 0xe8, 0x57, 0x0a, 0xb5, 0x06, 0x7a, 0xd2, - 0xdb, 0x11, 0x3a, 0x45, 0x51, 0xc0, 0x36, 0x8d, 0x0b, 0xe0, 0x2d, 0x90, 0x15, 0x0c, 0xee, 0xae, - 0xc5, 0x29, 0x76, 0x99, 0x5a, 0xdb, 0x7a, 0x7e, 0xd0, 0xaf, 0x80, 0x5a, 0x03, 0x6d, 0xef, 0x3e, - 0x11, 0x52, 0x04, 0xb0, 0x4d, 0xf5, 0x33, 0xbc, 0x03, 0x72, 0xc2, 0x02, 0x37, 0x0f, 0xac, 0xb6, - 0xd3, 0x71, 0xb8, 0x5a, 0xe1, 0x7a, 0x61, 0xd0, 0xaf, 0x64, 0x6a, 0x0d, 0x54, 0x6b, 0x1e, 0x6c, - 0x09, 0x31, 0xca, 0x60, 0x9b, 0x06, 0x2f, 0x71, 0x23, 0x9b, 0xb4, 0xf1, 0xb1, 0x5c, 0xf0, 0x21, - 0xa3, 0x86, 0x10, 0x07, 0x46, 0xf2, 0x05, 0xde, 0x05, 0x69, 0xda, 0xbb, 0xad, 0x0d, 0xd2, 0x72, - 0xde, 0xae, 0x8e, 0xce, 0x1b, 0xea, 0x29, 0xc3, 0x14, 0xed, 0xdd, 0x56, 0x56, 0xab, 0x60, 0x5e, - 0x5a, 0x85, 0xf3, 0xee, 0xed, 0xed, 0x31, 0xc2, 0x4d, 0x20, 0x37, 0x62, 0x49, 0xe0, 0xf4, 0x1c, - 0x3e, 0x92, 0x0a, 0xb8, 0x05, 0xe6, 0x68, 0x6f, 0x6d, 0x6c, 0xa1, 0x32, 0xe7, 0x58, 0x28, 0x54, - 0xa4, 0xbd, 0xb5, 0xe1, 0x25, 0xb9, 0x0e, 0x72, 0x82, 0x6d, 0x8f, 0x92, 0x9f, 0x77, 0x89, 0xdb, - 0x3c, 0x36, 0xb3, 0x8b, 0xc6, 0xf2, 0x34, 0xca, 0xd2, 0xde, 0xda, 0x83, 0x40, 0x06, 0x7f, 0x0a, - 0xae, 0x52, 0x22, 0xc2, 0x9a, 0xdc, 0x43, 0x96, 0x4f, 0xa8, 0xe3, 0xd9, 0x4e, 0xd3, 0xe1, 0xc7, - 0x66, 0x4e, 0x7e, 0x76, 0x69, 0x6c, 0x9c, 0x12, 0x2e, 0x36, 0xd6, 0x46, 0xcf, 0xf7, 0x5c, 0xe2, - 0x72, 0x74, 0x99, 0x86, 0xb2, 0x9d, 0x88, 0x00, 0x3e, 0x07, 0xa6, 0xe6, 0x6e, 0x7a, 0x5d, 0x97, - 0x0f, 0x91, 0xe7, 0x25, 0xf9, 0xf5, 0xc9, 0xe4, 0xeb, 0x02, 0x1e, 0xb2, 0x5f, 0xa1, 0x91, 0x30, - 0x4e, 0xbf, 0x09, 0xf2, 0xe2, 0x68, 0xd9, 0x5d, 0x7e, 0x6c, 0x35, 0x8f, 0x9b, 0x6d, 0x62, 0x16, - 0x26, 0x93, 0xd6, 0x5a, 0x2d, 0x4a, 0x5a, 0x98, 0x13, 0xbb, 0xd1, 0xe5, 0xc7, 0xeb, 0x02, 0x8a, - 0xb2, 0x1d, 0xdc, 0x0b, 0xdf, 0x60, 0x0d, 0xa4, 0x9a, 0xfb, 0xd8, 0x75, 0x49, 0x9b, 0x99, 0xc5, - 0xc5, 0xa9, 0xe5, 0xcc, 0xda, 0x6b, 0xa3, 0x24, 0x43, 0xc7, 0xba, 0xba, 0xae, 0xd0, 0x28, 0x34, - 0x13, 0x87, 0xd2, 0x77, 0xdc, 0x96, 0xc5, 0xda, 0x1e, 0x8f, 0xcd, 0x79, 0x49, 0xce, 0x79, 0x49, - 0xa8, 0x1e, 0xb7, 0x3d, 0x1e, 0x4d, 0xfc, 0x33, 0xf0, 0x52, 0x84, 0x1f, 0x5d, 0x71, 0x78, 0x9e, - 0x15, 0xbf, 0x1c, 0x90, 0x0e, 0x2f, 0xfb, 0x1b, 0xa0, 0xb8, 0x4b, 0x70, 0xd3, 0x73, 0x63, 0x5e, - 0xcc, 0x49, 0x2f, 0x0a, 0x4a, 0x1e, 0xfa, 0xb0, 0xf0, 0x5f, 0x49, 0x30, 0xab, 0x47, 0x22, 0xcc, - 0x74, 0x00, 0x8a, 0xcc, 0x0c, 0x65, 0xa6, 0xe4, 0x91, 0xeb, 0x2b, 0x00, 0x86, 0xf1, 0x27, 0x02, - 0x27, 0xd5, 0x48, 0x03, 0x4d, 0x04, 0xdf, 0x02, 0x73, 0x1d, 0xc7, 0x1d, 0x1b, 0xe3, 0xd4, 0xb9, - 0x76, 0x75, 0xc7, 0x71, 0x87, 0x87, 0x27, 0xd8, 0xc4, 0xaa, 0x7f, 0x8d, 0x60, 0x86, 0x8a, 0x62, - 0xd1, 0x47, 0xcf, 0x08, 0x71, 0xf1, 0x6e, 0x9b, 0x58, 0x6a, 0x90, 0x32, 0x62, 0xa5, 0x50, 0x56, - 0x09, 0x9f, 0x4a, 0xd9, 0xbd, 0xe9, 0x4f, 0x7f, 0x5b, 0x49, 0xa8, 0xbf, 0x4b, 0x1d, 0x90, 0xdf, - 0x70, 0xed, 0x86, 0x2c, 0xc1, 0xea, 0x14, 0xbb, 0x36, 0xbc, 0x02, 0x92, 0x8e, 0x2d, 0xa7, 0x2a, - 0x5d, 0x9f, 0x19, 0xf4, 0x2b, 0xc9, 0xcd, 0x06, 0x4a, 0x3a, 0x36, 0x84, 0x60, 0xda, 0xc5, 0x3a, - 0x88, 0xa7, 0x91, 0x7c, 0x86, 0x2f, 0x81, 0xa9, 0x2e, 0x6d, 0xcb, 0xa1, 0xa7, 0xeb, 0xb3, 0x83, - 0x7e, 0x65, 0xea, 0x29, 0xda, 0x42, 0x42, 0x06, 0xe7, 0xc1, 0xa5, 0xb6, 0xd7, 0xf2, 0x98, 0x39, - 0xbd, 0x38, 0xb5, 0x9c, 0x46, 0xea, 0x65, 0xc9, 0x8e, 0x7d, 0xee, 0xa1, 0x67, 0x93, 0xb6, 0x48, - 0x28, 0xbb, 0xe2, 0xbb, 0x56, 0xf8, 0x51, 0x99, 0x50, 0xa4, 0x2f, 0x9b, 0x0d, 0x34, 0x2b, 0x95, - 0x9b, 0x81, 0x5b, 0xc9, 0x53, 0xdd, 0x9a, 0x8a, 0xdc, 0x5a, 0xfa, 0xd7, 0x24, 0x78, 0x39, 0xfc, - 0xcc, 0x07, 0x84, 0x8a, 0x8c, 0xbe, 0x19, 0xd5, 0x43, 0xf0, 0xd1, 0xd8, 0x37, 0xef, 0xc6, 0xbe, - 0x39, 0xf8, 0xa2, 0xf2, 0x1a, 0x78, 0xf5, 0xe3, 0x8f, 0xf0, 0xca, 0xdf, 0xdd, 0x5a, 0xf9, 0xc1, - 0xf3, 0xe5, 0xfb, 0xf7, 0x3e, 0x5a, 0x79, 0x7e, 0x3f, 0x78, 0x7d, 0xe3, 0xef, 0xd7, 0x6e, 0xfe, - 0xe3, 0x8d, 0x7f, 0xf8, 0xf8, 0x46, 0xef, 0xb5, 0xc8, 0xb9, 0x47, 0x20, 0xd5, 0x11, 0xa3, 0xb1, - 0x42, 0x17, 0x25, 0xa1, 0x1c, 0xe1, 0x85, 0x08, 0x25, 0xcb, 0xa6, 0x2d, 0x76, 0xef, 0x3e, 0xa6, - 0xf6, 0x11, 0xa6, 0xc4, 0x3a, 0x54, 0x03, 0xd0, 0x23, 0x2c, 0x04, 0x72, 0x3d, 0x2e, 0x01, 0xdd, - 0x73, 0x68, 0x67, 0x08, 0x3a, 0xad, 0xa0, 0x81, 0x5c, 0x43, 0x97, 0xfe, 0x65, 0x16, 0x14, 0x47, - 0xe7, 0x05, 0xfe, 0x04, 0x4c, 0x39, 0x36, 0x93, 0xf3, 0x90, 0x59, 0xfb, 0xee, 0xe8, 0x86, 0x3b, - 0x63, 0x1a, 0x63, 0xf5, 0x91, 0x60, 0x80, 0xcf, 0x40, 0x41, 0x1b, 0x86, 0x7e, 0x24, 0xe5, 0x2e, - 0x5e, 0x98, 0x10, 0x7b, 0x34, 0x5d, 0x1d, 0x0e, 0xfa, 0x95, 0xfc, 0x96, 0x87, 0xf0, 0xb3, 0xda, - 0xb6, 0x96, 0xa1, 0xbc, 0x86, 0x06, 0x1e, 0x62, 0x30, 0x17, 0x10, 0xfb, 0xfb, 0xc7, 0x43, 0xf3, - 0x31, 0x81, 0x7c, 0xe7, 0xdd, 0x0f, 0x03, 0xf2, 0xcb, 0x83, 0x7e, 0xa5, 0xa4, 0xc9, 0x23, 0x31, - 0x2a, 0x69, 0xf4, 0xce, 0xfe, 0x71, 0xf0, 0x89, 0xfb, 0xa0, 0x14, 0x9e, 0x7c, 0xcb, 0x6f, 0x63, - 0x57, 0xac, 0xa4, 0x9c, 0x45, 0x95, 0xed, 0xc3, 0xd3, 0xbf, 0xd3, 0xc6, 0xee, 0x66, 0x03, 0x15, - 0xf6, 0x86, 0x04, 0x62, 0x7b, 0xce, 0xf8, 0xfb, 0x1e, 0xf7, 0x98, 0x79, 0x49, 0xee, 0x77, 0xfd, - 0x06, 0x97, 0x41, 0x91, 0x75, 0x7d, 0xdf, 0xa3, 0x9c, 0x59, 0xcd, 0x36, 0x66, 0xcc, 0xda, 0x95, - 0x95, 0x40, 0x0a, 0xe5, 0x03, 0xf9, 0xba, 0x10, 0xd7, 0x27, 0x20, 0x9b, 0xb2, 0x00, 0x18, 0x45, - 0xae, 0xc3, 0x0e, 0xb8, 0x62, 0x93, 0x3d, 0xdc, 0x6d, 0x73, 0xab, 0x83, 0x9b, 0x96, 0x1f, 0x86, - 0x71, 0x5d, 0xec, 0xbd, 0x72, 0x66, 0xac, 0xaf, 0x9b, 0x83, 0x7e, 0x65, 0xbe, 0xa1, 0x08, 0x86, - 0x34, 0x68, 0x5e, 0xd3, 0x3e, 0xc4, 0xcd, 0x58, 0xc9, 0x77, 0x1d, 0xe4, 0x44, 0xbc, 0x8b, 0x22, - 0x63, 0x5a, 0xe5, 0xdd, 0x8e, 0x13, 0x85, 0x5e, 0x09, 0xc2, 0xbd, 0x18, 0x08, 0x68, 0x10, 0xee, - 0x45, 0xa0, 0x45, 0x90, 0xa5, 0x84, 0x11, 0xce, 0x54, 0x19, 0x2b, 0x0b, 0x81, 0x14, 0x02, 0x4a, - 0x26, 0xea, 0x57, 0xf8, 0x43, 0x50, 0xea, 0x32, 0xc2, 0xac, 0x3b, 0x6b, 0xd6, 0xae, 0xa3, 0x2b, - 0x6d, 0x99, 0xe7, 0x53, 0xf5, 0xd2, 0xa0, 0x5f, 0xc9, 0x3d, 0x65, 0x84, 0xdd, 0x59, 0xab, 0x3b, - 0xb2, 0xde, 0x46, 0xb9, 0x6e, 0xfc, 0x55, 0xf8, 0x10, 0xce, 0xa0, 0xc8, 0xb0, 0x32, 0xe3, 0xa7, - 0x50, 0x36, 0x10, 0xbe, 0xe7, 0x39, 0x2e, 0xbc, 0x09, 0xa0, 0xf6, 0x41, 0x66, 0x72, 0xd7, 0x73, - 0x9b, 0x84, 0xc9, 0xf4, 0x9d, 0x42, 0x45, 0xa5, 0x11, 0xb8, 0x6d, 0x29, 0x87, 0xcf, 0x01, 0x0c, - 0xa6, 0x7a, 0xcf, 0xa3, 0x1d, 0xcc, 0xe5, 0x34, 0x17, 0xe4, 0x34, 0x2f, 0x8f, 0x4d, 0xb3, 0x6a, - 0x78, 0x76, 0xf0, 0x71, 0xdb, 0xc3, 0xf6, 0x83, 0x10, 0x5f, 0x9f, 0x16, 0x07, 0x05, 0x95, 0x34, - 0x53, 0xa4, 0xd0, 0x31, 0xf8, 0x9f, 0x66, 0x40, 0xe6, 0x61, 0x6d, 0xfd, 0x31, 0xe1, 0x5c, 0xf4, - 0x34, 0xf0, 0x3a, 0x98, 0xed, 0x32, 0x62, 0x61, 0x9b, 0xca, 0x53, 0x99, 0xaa, 0x83, 0x41, 0xbf, - 0x32, 0xf3, 0x94, 0x91, 0x5a, 0x03, 0xa1, 0x99, 0x2e, 0x23, 0x35, 0x9b, 0xc2, 0x9b, 0x40, 0x94, - 0x8e, 0x56, 0x07, 0xd3, 0x96, 0xa3, 0x0e, 0x5a, 0xae, 0x9e, 0x1b, 0xf4, 0x2b, 0xe9, 0x5a, 0x03, - 0x3d, 0x94, 0x42, 0x94, 0xc6, 0x36, 0x55, 0x8f, 0xf0, 0x7d, 0x50, 0xd0, 0xbb, 0x4f, 0xd6, 0x45, - 0x5e, 0x97, 0xeb, 0x06, 0xe8, 0xa5, 0xb1, 0xc6, 0xa0, 0xa1, 0x7b, 0x5b, 0x75, 0xbc, 0x7f, 0x23, - 0xfa, 0x82, 0x9c, 0xb4, 0xad, 0x3f, 0x51, 0x96, 0x11, 0x59, 0x33, 0x24, 0x9b, 0xbe, 0x28, 0xd9, - 0x7a, 0x40, 0xf6, 0x11, 0xb8, 0xca, 0x38, 0xe6, 0x5d, 0x36, 0x5e, 0xb0, 0x5d, 0x3a, 0x3f, 0xe9, - 0x65, 0xc5, 0x31, 0x5a, 0xb1, 0xbd, 0x0d, 0x4c, 0x4d, 0x3e, 0x5e, 0xb1, 0xa9, 0x5e, 0xeb, 0x8a, - 0xd2, 0x8f, 0x15, 0x63, 0x1b, 0xf1, 0x0a, 0x79, 0xf6, 0x94, 0xf5, 0x8e, 0xd6, 0x2c, 0xa8, 0x96, - 0x3f, 0xc0, 0xed, 0x2e, 0x89, 0x95, 0xcc, 0xcf, 0x27, 0x57, 0xc0, 0xea, 0x9c, 0x56, 0xcf, 0x22, - 0x1c, 0xca, 0xeb, 0x8a, 0x76, 0xbc, 0x24, 0xae, 0x8d, 0x96, 0xc4, 0x69, 0x49, 0x7c, 0x6d, 0x6c, - 0xca, 0x9e, 0x6e, 0xba, 0xfc, 0x7b, 0x77, 0x15, 0xcd, 0x50, 0xc1, 0xbc, 0xf0, 0x63, 0x90, 0x8d, - 0xfb, 0x0e, 0x57, 0xc0, 0xa5, 0x43, 0xf1, 0x20, 0xb7, 0xde, 0x19, 0x6d, 0x81, 0x42, 0x2d, 0x6c, - 0x02, 0x38, 0xee, 0x29, 0xbc, 0x33, 0x4c, 0xf2, 0x15, 0x65, 0x8c, 0xc2, 0x2e, 0xfd, 0x67, 0x1a, - 0xa4, 0xc4, 0x0c, 0x70, 0xcc, 0x09, 0x44, 0x00, 0x36, 0xbb, 0x94, 0x12, 0xb1, 0x68, 0x51, 0x7c, - 0x33, 0xce, 0x13, 0xdf, 0xf4, 0x69, 0xd3, 0xe6, 0xb1, 0x40, 0x86, 0xc4, 0x61, 0x66, 0x0e, 0x25, - 0x76, 0x9c, 0x33, 0x79, 0x01, 0x4e, 0x6d, 0x1e, 0xe3, 0x7c, 0x1b, 0x64, 0xd5, 0xfd, 0x95, 0x8a, - 0xd9, 0x3a, 0x29, 0x5d, 0x1e, 0x65, 0x93, 0x91, 0x1b, 0x65, 0x14, 0x54, 0xbe, 0x4c, 0x4a, 0x97, - 0xd3, 0xff, 0x27, 0xe9, 0xf2, 0x39, 0x58, 0x08, 0xef, 0x0b, 0x1c, 0xda, 0x21, 0xb6, 0x15, 0x56, - 0xb7, 0x98, 0xeb, 0x43, 0x75, 0xd6, 0x7d, 0xc0, 0xb4, 0xbc, 0x0b, 0xb8, 0x1a, 0xdc, 0x2b, 0x48, - 0x8a, 0x86, 0x66, 0xa8, 0x71, 0xf8, 0x16, 0x30, 0x25, 0xbd, 0x4d, 0x0e, 0x2d, 0x7d, 0xb8, 0xc2, - 0x0b, 0x11, 0x75, 0xa6, 0xe6, 0x84, 0xbe, 0x41, 0x0e, 0x1f, 0x4b, 0xad, 0xbe, 0x19, 0x41, 0xe0, - 0x72, 0xd4, 0x1f, 0xc4, 0xcf, 0xe1, 0xac, 0x1c, 0x74, 0x79, 0x2c, 0x8d, 0xeb, 0x66, 0x40, 0x1d, - 0x4a, 0x34, 0xe7, 0x0f, 0xbd, 0xab, 0x43, 0x4a, 0xc0, 0x35, 0x9f, 0xb8, 0xb6, 0xa0, 0xc5, 0xbe, - 0xdf, 0x76, 0x9a, 0x32, 0x2c, 0x84, 0xc3, 0xd5, 0xc7, 0x6c, 0xbc, 0x7f, 0x8a, 0xb0, 0xc1, 0xb8, - 0xd0, 0x82, 0x26, 0x9a, 0xa0, 0x83, 0x1b, 0xa0, 0xf8, 0xf3, 0x2e, 0xe9, 0x12, 0xdb, 0xa2, 0x84, - 0xf9, 0x9e, 0xcb, 0x08, 0x33, 0xd3, 0xb2, 0xab, 0x9a, 0xb4, 0x54, 0xeb, 0x5e, 0xa7, 0x83, 0x5d, - 0x1b, 0x15, 0x94, 0x0d, 0x0a, 0x4c, 0x04, 0x4d, 0xe0, 0xad, 0x3c, 0x7d, 0x8c, 0x33, 0x13, 0x7c, - 0x35, 0x8d, 0xb6, 0x41, 0xda, 0x04, 0xfe, 0x0d, 0x80, 0xda, 0x1b, 0x99, 0xc0, 0x70, 0xb3, 0x49, - 0x7c, 0x95, 0x4a, 0x27, 0x0c, 0x35, 0x38, 0x4f, 0x55, 0x91, 0xd3, 0x6a, 0x12, 0x8a, 0xf4, 0x60, - 0x22, 0x09, 0x7c, 0x08, 0xe6, 0x03, 0xcf, 0x24, 0xa7, 0x76, 0x4f, 0x26, 0xde, 0x09, 0x77, 0x64, - 0xc2, 0x52, 0xbb, 0x83, 0xa0, 0x36, 0x8c, 0xc9, 0xe0, 0x2d, 0x30, 0x4f, 0x7b, 0xd6, 0x91, 0xe3, - 0xda, 0xde, 0x11, 0xb3, 0xf0, 0x21, 0x76, 0xda, 0xa2, 0xfb, 0xd0, 0xe9, 0x18, 0xd2, 0xde, 0x33, - 0xa5, 0xaa, 0x05, 0x9a, 0x85, 0xff, 0x30, 0x00, 0x88, 0xf9, 0xb3, 0x04, 0x66, 0x7d, 0x95, 0x44, - 0xe5, 0x89, 0xcf, 0xd6, 0x53, 0x83, 0x2f, 0x2a, 0xd3, 0x7e, 0xa6, 0xf7, 0x0a, 0x0a, 0x14, 0xf0, - 0x87, 0x60, 0x36, 0x70, 0x33, 0xf9, 0x95, 0x6e, 0xea, 0xf3, 0x1b, 0x58, 0xc0, 0xb7, 0xce, 0x7f, - 0x09, 0xa8, 0x2c, 0x25, 0x5c, 0xa7, 0xeb, 0x7f, 0x36, 0x41, 0x3a, 0x2c, 0x8b, 0xe1, 0x3b, 0xf1, - 0xf2, 0xf9, 0xc6, 0xa9, 0xe5, 0xf3, 0x19, 0x75, 0xf3, 0x3a, 0x00, 0x4d, 0x4a, 0xb0, 0xbe, 0xaf, - 0x4b, 0x5e, 0xe4, 0xbe, 0x4e, 0xdb, 0xd5, 0xb8, 0x20, 0xe9, 0xfa, 0x76, 0x40, 0x32, 0x75, 0x11, - 0x12, 0x6d, 0x57, 0xe3, 0x61, 0x2f, 0x35, 0x1d, 0x6b, 0xf1, 0x16, 0x41, 0xc6, 0x26, 0xac, 0x49, - 0x1d, 0x5f, 0x9c, 0x09, 0x19, 0x3e, 0xd2, 0x28, 0x2e, 0x82, 0x9b, 0x00, 0x60, 0xce, 0xa9, 0xb3, - 0xdb, 0xe5, 0x84, 0x99, 0x33, 0x72, 0x47, 0xbf, 0x71, 0xea, 0x44, 0x54, 0x6b, 0x21, 0x76, 0xc3, - 0xe5, 0xf4, 0x18, 0xc5, 0x8c, 0xe1, 0xcf, 0x40, 0x46, 0xc7, 0x42, 0x4b, 0x4c, 0xea, 0xec, 0xc5, - 0x7b, 0x12, 0x79, 0xbf, 0x16, 0xc8, 0x1b, 0x0c, 0x81, 0xc3, 0x00, 0xc3, 0x60, 0x1d, 0x40, 0x46, - 0xa8, 0x0c, 0xd6, 0x3e, 0xf5, 0xf6, 0x9c, 0x36, 0x11, 0x55, 0x7e, 0x4a, 0x56, 0xf9, 0xf2, 0x5e, - 0xf0, 0xb1, 0xd2, 0xee, 0x28, 0xe5, 0x66, 0x03, 0x15, 0xd9, 0xb0, 0xc4, 0x86, 0x77, 0xc1, 0x15, - 0x7d, 0xe5, 0x6c, 0x09, 0x1d, 0xa1, 0xf2, 0x8a, 0x9a, 0x30, 0x26, 0x53, 0x6f, 0x1a, 0xcd, 0x6b, - 0xed, 0x63, 0xa9, 0xac, 0x29, 0x1d, 0xfc, 0x11, 0x58, 0x88, 0x07, 0xa8, 0x11, 0x4b, 0x20, 0x2d, - 0xcd, 0x18, 0x62, 0xd8, 0xba, 0x0a, 0xe6, 0xe4, 0xb1, 0x1c, 0x31, 0xcb, 0x48, 0xb3, 0x92, 0x50, - 0x0d, 0xe3, 0x1f, 0x80, 0x74, 0xdb, 0x53, 0x44, 0xcc, 0xcc, 0xca, 0xf5, 0x58, 0x3e, 0x7d, 0x3d, - 0xb6, 0x02, 0xa8, 0x5a, 0x8e, 0xc8, 0x74, 0x62, 0xef, 0x92, 0x3b, 0x77, 0xef, 0x92, 0x9f, 0xd8, - 0xbb, 0x4c, 0xc8, 0x7a, 0x85, 0x6f, 0xb3, 0x49, 0x2c, 0x7e, 0xdb, 0x4d, 0x62, 0xe9, 0x02, 0x4d, - 0xe2, 0xe9, 0x8d, 0x1b, 0xfc, 0x7f, 0x69, 0xdc, 0xe6, 0xce, 0xd3, 0xb8, 0xcd, 0x9f, 0xa3, 0x71, - 0xbb, 0x7c, 0xbe, 0xc6, 0xed, 0xca, 0xd7, 0x6d, 0xdc, 0xae, 0x9e, 0xbb, 0x71, 0x33, 0x4f, 0x69, - 0xdc, 0xde, 0x02, 0x69, 0xea, 0x79, 0xdc, 0x92, 0x61, 0xfe, 0x25, 0x39, 0xbb, 0xe6, 0x58, 0x29, - 0xeb, 0x79, 0x5c, 0xc4, 0x78, 0x94, 0xa2, 0xfa, 0x09, 0x7e, 0x00, 0x66, 0x5c, 0xc2, 0xc5, 0xba, - 0x2e, 0xc8, 0xc4, 0x73, 0xff, 0x4f, 0xfd, 0xca, 0xda, 0x85, 0x7e, 0x70, 0xda, 0x26, 0x7c, 0xb3, - 0x31, 0xe8, 0x57, 0x2e, 0xc9, 0x07, 0x74, 0xc9, 0x25, 0x5c, 0x5e, 0x10, 0x65, 0xc5, 0x8a, 0x33, - 0x5d, 0xdd, 0x9b, 0x2f, 0x4f, 0x4e, 0x3c, 0xb1, 0x06, 0x40, 0xdd, 0xe0, 0xc7, 0x04, 0x28, 0xd3, - 0xc1, 0xcd, 0xb0, 0x47, 0x5c, 0x07, 0x69, 0x49, 0x28, 0x92, 0xbb, 0x79, 0x6d, 0xf2, 0xf8, 0x82, - 0xe4, 0x5f, 0xcf, 0x0e, 0xfa, 0x95, 0xb0, 0xb4, 0x46, 0x29, 0xc1, 0x23, 0x8b, 0xec, 0xdb, 0x60, - 0x96, 0xa9, 0x54, 0x67, 0xbe, 0x22, 0x29, 0xae, 0x9e, 0x92, 0x09, 0x51, 0x80, 0x83, 0xef, 0x80, - 0xa0, 0x20, 0xb1, 0x02, 0xd3, 0xf2, 0xd9, 0xa6, 0x79, 0x8d, 0x0f, 0x7e, 0xd9, 0xbb, 0x01, 0xf2, - 0x61, 0xfd, 0x28, 0x17, 0xd1, 0xac, 0xc8, 0xaa, 0x31, 0xab, 0xab, 0x46, 0xb9, 0x80, 0xf0, 0x75, - 0x50, 0xe8, 0x32, 0x62, 0x47, 0x28, 0x66, 0x2e, 0x2e, 0x4e, 0x2d, 0xe7, 0xe4, 0xd6, 0xb1, 0x03, - 0x18, 0x13, 0x38, 0xc9, 0x16, 0xed, 0x09, 0xf3, 0xd5, 0xe8, 0x47, 0xb4, 0x70, 0x43, 0xc0, 0xef, - 0x6b, 0x1c, 0xfd, 0x44, 0xb7, 0x82, 0xb7, 0xcc, 0x25, 0xd9, 0x33, 0x17, 0x07, 0xfd, 0x4a, 0x76, - 0x0b, 0x33, 0x8e, 0xde, 0x93, 0x4d, 0xe0, 0x2d, 0xe5, 0x08, 0xfa, 0x44, 0xbd, 0x8d, 0x1b, 0xde, - 0x36, 0xaf, 0x4f, 0x34, 0xbc, 0x3d, 0x64, 0x78, 0x1b, 0x7e, 0x0c, 0x5e, 0x1e, 0xad, 0x93, 0x29, - 0x69, 0x12, 0xe7, 0x50, 0xa5, 0xe8, 0x1b, 0x17, 0xa9, 0xc3, 0xc3, 0x62, 0x1a, 0x69, 0x86, 0x9a, - 0x38, 0x71, 0x19, 0xf5, 0xd3, 0x94, 0xda, 0x03, 0xaf, 0x9d, 0x12, 0xe8, 0x04, 0x44, 0xad, 0x3b, - 0xf0, 0xc3, 0x67, 0xb8, 0x02, 0xe0, 0xae, 0xbc, 0x83, 0x38, 0x16, 0xb5, 0x78, 0x93, 0xb8, 0x1c, - 0xb7, 0x88, 0xf9, 0xfa, 0xa2, 0xb1, 0x9c, 0x44, 0x25, 0xad, 0xd9, 0x09, 0x15, 0xf0, 0x3b, 0xa0, - 0x10, 0xf6, 0x10, 0xfa, 0xc6, 0xe1, 0x3b, 0x8b, 0xc6, 0xf2, 0x25, 0x94, 0x0f, 0xc4, 0xfa, 0x9e, - 0x01, 0x8b, 0x43, 0x2a, 0xac, 0x2c, 0x6c, 0x53, 0x7d, 0x07, 0xcd, 0xcc, 0x65, 0x99, 0x83, 0xc6, - 0xa2, 0x9b, 0xba, 0x8e, 0xd6, 0xb7, 0x26, 0x2a, 0x03, 0x23, 0x69, 0x5c, 0x6b, 0x20, 0xa5, 0x63, - 0xe2, 0x64, 0x4b, 0x89, 0x4d, 0xb5, 0x04, 0x36, 0x40, 0x5e, 0x7f, 0x22, 0xa0, 0x7f, 0xe3, 0x1c, - 0xf4, 0x28, 0xa7, 0x8c, 0x02, 0x96, 0xf7, 0x80, 0x66, 0x0e, 0xbb, 0x05, 0x66, 0xbe, 0x29, 0x79, - 0x2a, 0x63, 0xcd, 0x6a, 0x30, 0x44, 0xcd, 0x54, 0x50, 0x86, 0x81, 0x98, 0x89, 0x36, 0x44, 0x57, - 0xe4, 0x93, 0xba, 0x10, 0x66, 0x7e, 0x57, 0xf2, 0x9e, 0xaf, 0x0d, 0x51, 0x44, 0x13, 0x54, 0x0c, - 0xbe, 0x0b, 0x40, 0xec, 0x0e, 0xea, 0xe6, 0xc5, 0xee, 0xa0, 0x50, 0xcc, 0x16, 0x62, 0x90, 0xf7, - 0xa9, 0x77, 0xe8, 0x88, 0xf3, 0x48, 0xa8, 0x88, 0x76, 0x2b, 0x32, 0x8b, 0xdd, 0x13, 0x91, 0x7a, - 0x27, 0xd2, 0x5c, 0xe4, 0xea, 0x3a, 0x17, 0x63, 0xdc, 0xb4, 0x61, 0x03, 0x94, 0x42, 0x81, 0x08, - 0x16, 0x36, 0xe6, 0xd8, 0xac, 0xea, 0x48, 0x31, 0xba, 0xe7, 0x1f, 0xcb, 0x7f, 0x86, 0x40, 0xc5, - 0xb8, 0x45, 0x03, 0x73, 0xbc, 0xf0, 0x63, 0x50, 0x18, 0x29, 0x17, 0x61, 0x11, 0x4c, 0x1d, 0x10, - 0xf5, 0x53, 0x4e, 0x1a, 0x89, 0x47, 0x38, 0x1f, 0x5c, 0x36, 0xa8, 0x5f, 0x26, 0xd4, 0xcb, 0xbd, - 0xe4, 0xdb, 0xc6, 0xc2, 0x07, 0x20, 0x3f, 0x5c, 0xdd, 0x4c, 0xb0, 0xae, 0xc6, 0xad, 0x27, 0x04, - 0xd1, 0x80, 0x20, 0xc6, 0xab, 0xfb, 0x80, 0x77, 0x01, 0x08, 0xab, 0x28, 0x06, 0xef, 0x81, 0x4c, - 0xf4, 0xcf, 0x2c, 0xa2, 0x1f, 0x98, 0x92, 0x77, 0x57, 0xa7, 0x95, 0x5d, 0x08, 0x90, 0xd0, 0x76, - 0xe9, 0x67, 0xe0, 0xca, 0xba, 0xac, 0xe4, 0x23, 0xb5, 0x6e, 0x54, 0xea, 0x00, 0x44, 0xac, 0xba, - 0xc9, 0x38, 0x9d, 0x34, 0xd6, 0x59, 0xa4, 0x43, 0xfa, 0xa5, 0x7f, 0x33, 0xc0, 0x95, 0xa7, 0xb2, - 0xc6, 0xff, 0x36, 0xe8, 0xe1, 0x7d, 0x00, 0xa2, 0x7f, 0x77, 0x39, 0xb5, 0x7d, 0x79, 0x20, 0x20, - 0x0f, 0x31, 0x3b, 0xd0, 0x0d, 0x55, 0x7a, 0x2f, 0x10, 0x2c, 0xfd, 0xb7, 0x01, 0xe6, 0x7e, 0x42, - 0xf8, 0x98, 0x73, 0x4f, 0x40, 0x3e, 0x72, 0xce, 0xfa, 0xfa, 0x4d, 0x56, 0x96, 0x44, 0x7a, 0xf6, - 0xcd, 0xdd, 0xfd, 0x1f, 0x03, 0x5c, 0xde, 0x72, 0x58, 0xe4, 0x2f, 0x0b, 0x1c, 0xfe, 0x10, 0x14, - 0xe2, 0x01, 0x20, 0xf2, 0xf8, 0xf5, 0x33, 0x8e, 0xfe, 0x64, 0x9f, 0xf3, 0x38, 0x8e, 0xf8, 0xe6, - 0x5e, 0x8b, 0x43, 0xe2, 0x51, 0x9b, 0x50, 0xfd, 0x2b, 0x92, 0x7a, 0x91, 0x3f, 0xd2, 0xc9, 0xff, - 0x34, 0x50, 0xff, 0xc9, 0xa2, 0x5e, 0x44, 0x1b, 0xe8, 0x8b, 0x74, 0xa0, 0xfe, 0x6f, 0x45, 0x3e, - 0x2f, 0xfd, 0xca, 0x00, 0x73, 0x8f, 0x27, 0x2c, 0xd2, 0xf7, 0xc1, 0xcc, 0x79, 0x77, 0x8f, 0xf2, - 0x49, 0xc3, 0xbf, 0xf1, 0x88, 0xde, 0x7c, 0x00, 0x40, 0x94, 0xdc, 0x60, 0x09, 0xe4, 0x76, 0x1e, - 0x3d, 0xdb, 0x40, 0xd6, 0xd3, 0xed, 0xf7, 0xb7, 0x1f, 0x3d, 0xdb, 0x2e, 0x26, 0x22, 0x51, 0xbd, - 0xf6, 0xe4, 0xc9, 0x06, 0xfa, 0xb0, 0x68, 0x40, 0x08, 0xf2, 0x4a, 0xb4, 0xf1, 0xb7, 0x4f, 0x36, - 0xd0, 0x76, 0x6d, 0xab, 0x98, 0xac, 0xff, 0xbb, 0xf1, 0xd9, 0x8b, 0xb2, 0xf1, 0xf9, 0x8b, 0xb2, - 0xf1, 0xc7, 0x17, 0xe5, 0xc4, 0x9f, 0x5f, 0x94, 0x13, 0x7f, 0x79, 0x51, 0x4e, 0xfc, 0xf5, 0x45, - 0x39, 0xf1, 0xe5, 0x8b, 0xb2, 0xf1, 0x8b, 0x41, 0xd9, 0xf8, 0xe5, 0xa0, 0x9c, 0xf8, 0xdd, 0xa0, - 0x6c, 0xfc, 0x7e, 0x50, 0x4e, 0x7c, 0x3a, 0x28, 0x27, 0xfe, 0x30, 0x28, 0x27, 0x3e, 0x1b, 0x94, - 0x8d, 0xcf, 0x07, 0x65, 0xe3, 0x8f, 0x83, 0x72, 0xe2, 0xcf, 0x83, 0xb2, 0xf1, 0x97, 0x41, 0x39, - 0xf1, 0xd7, 0x41, 0xd9, 0xf8, 0x72, 0x50, 0x4e, 0xfc, 0xe2, 0xa4, 0x9c, 0xf8, 0xe5, 0x49, 0xd9, - 0xf8, 0xf5, 0x49, 0x39, 0xf1, 0x9b, 0x93, 0xb2, 0xf1, 0xdb, 0x93, 0x72, 0xe2, 0x77, 0x27, 0xe5, - 0xc4, 0xef, 0x4f, 0xca, 0xc6, 0xa7, 0x27, 0x65, 0xe3, 0x0f, 0x27, 0x65, 0xe3, 0xa7, 0x37, 0xcf, - 0x5b, 0x55, 0x72, 0xd7, 0xdf, 0xdd, 0x9d, 0x91, 0x33, 0x72, 0xe7, 0x7f, 0x03, 0x00, 0x00, 0xff, - 0xff, 0x6f, 0xf4, 0x9e, 0xcd, 0x43, 0x27, 0x00, 0x00, + golang_proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_1fd831da224133be) +} + +var fileDescriptor_end_device_1fd831da224133be = []byte{ + // 3542 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5a, 0x4b, 0x6c, 0x5b, 0xd7, + 0x99, 0x26, 0x25, 0x59, 0x22, 0x7f, 0x4a, 0x24, 0x75, 0x24, 0xdb, 0x37, 0x8a, 0x43, 0x2a, 0xb2, + 0x93, 0x2a, 0x69, 0x44, 0xdb, 0xb2, 0xd3, 0x87, 0xdb, 0xc2, 0x21, 0x45, 0x39, 0x91, 0x2b, 0xcb, + 0x9a, 0xe3, 0xd7, 0xa4, 0xad, 0x73, 0x71, 0xc4, 0x7b, 0x24, 0xdf, 0x88, 0xbc, 0xf7, 0xf6, 0x9c, + 0x43, 0x89, 0x9a, 0x07, 0xd0, 0xcd, 0x00, 0xdd, 0xb5, 0x8b, 0x19, 0xa0, 0x9b, 0x01, 0x8a, 0xc1, + 0x0c, 0x50, 0x0c, 0x66, 0xd1, 0x65, 0x96, 0x5d, 0x66, 0x99, 0x65, 0xd1, 0x05, 0x53, 0x53, 0x9b, + 0x2e, 0x0b, 0xcc, 0x26, 0xcb, 0xc1, 0x79, 0xdc, 0x07, 0x1f, 0x52, 0xa4, 0x64, 0xd2, 0x8d, 0x70, + 0xef, 0xff, 0x7f, 0xff, 0x77, 0xff, 0xf3, 0xfa, 0x1f, 0x87, 0x82, 0xa5, 0xa6, 0xcf, 0xc8, 0x21, + 0xf1, 0x56, 0xb8, 0x20, 0x8d, 0xfd, 0xeb, 0x24, 0x70, 0xaf, 0x53, 0xcf, 0xb1, 0x1d, 0x7a, 0xe0, + 0x36, 0x68, 0x25, 0x60, 0xbe, 0xf0, 0x51, 0x5e, 0x08, 0xaf, 0x62, 0x70, 0x95, 0x83, 0x5b, 0x0b, + 0x2b, 0x7b, 0xae, 0x78, 0xd1, 0xde, 0xa9, 0x34, 0xfc, 0xd6, 0xf5, 0x3d, 0x7f, 0xcf, 0xbf, 0xae, + 0x60, 0x3b, 0xed, 0x5d, 0xf5, 0xa6, 0x5e, 0xd4, 0x93, 0x36, 0x5f, 0xf8, 0x4e, 0x02, 0xde, 0x3a, + 0x74, 0xc5, 0xbe, 0x7f, 0x78, 0x7d, 0xcf, 0x5f, 0x51, 0xca, 0x95, 0x03, 0xd2, 0x74, 0x1d, 0x22, + 0x7c, 0xc6, 0xaf, 0x47, 0x8f, 0xc6, 0xee, 0xca, 0x9e, 0xef, 0xef, 0x35, 0xa9, 0xf2, 0x89, 0x78, + 0x9e, 0x2f, 0x88, 0x70, 0x7d, 0x8f, 0x1b, 0x6d, 0xc9, 0x68, 0xa3, 0x6f, 0x3b, 0x6d, 0xa6, 0x00, + 0x46, 0xbf, 0x38, 0xa8, 0xdf, 0x75, 0x69, 0xd3, 0xb1, 0x5b, 0x84, 0xef, 0x0f, 0xf0, 0x47, 0x08, + 0x2e, 0x58, 0xbb, 0x21, 0x8c, 0xb6, 0x3c, 0xa8, 0x15, 0x6e, 0x8b, 0x72, 0x41, 0x5a, 0xc1, 0x49, + 0x0e, 0x1c, 0x32, 0x12, 0x04, 0x94, 0x85, 0x0e, 0x5e, 0x1d, 0x9e, 0x59, 0xd7, 0xa1, 0x9e, 0x70, + 0x77, 0xdd, 0x18, 0x74, 0x65, 0x18, 0xf4, 0xb1, 0xef, 0x7a, 0x27, 0x6b, 0xf7, 0xe9, 0x51, 0x68, + 0x5b, 0x1e, 0xd6, 0x86, 0x8b, 0x64, 0xa6, 0x60, 0x18, 0xd0, 0xa2, 0x9c, 0x93, 0x3d, 0xca, 0x4f, + 0x43, 0x08, 0xe2, 0x10, 0x41, 0x34, 0x62, 0xe9, 0x57, 0xe3, 0x30, 0xf5, 0x88, 0x72, 0xee, 0xfa, + 0x1e, 0x7a, 0x06, 0x19, 0x87, 0x1e, 0xd8, 0xc4, 0x71, 0x98, 0x35, 0xb6, 0x98, 0x5e, 0x9e, 0xae, + 0xfd, 0xf0, 0xd3, 0x6e, 0x39, 0xf5, 0xa7, 0x6e, 0xf9, 0xf6, 0x9e, 0x5f, 0x11, 0x2f, 0xa8, 0x78, + 0xe1, 0x7a, 0x7b, 0xbc, 0xe2, 0x51, 0x71, 0xe8, 0xb3, 0xfd, 0xeb, 0xfd, 0xe4, 0xc1, 0xfe, 0xde, + 0x75, 0x71, 0x14, 0x50, 0x5e, 0xa9, 0xd3, 0x83, 0xaa, 0xe3, 0x30, 0x3c, 0xe5, 0xe8, 0x07, 0xf4, + 0x7d, 0x98, 0x90, 0xe3, 0xb2, 0xc6, 0x17, 0xd3, 0xcb, 0xb9, 0xd5, 0x57, 0x2b, 0xfd, 0xfb, 0xad, + 0x62, 0xbe, 0xff, 0x63, 0x7a, 0xc4, 0x6b, 0x19, 0xf9, 0xc5, 0xcf, 0xba, 0xe5, 0x34, 0x56, 0x26, + 0xe8, 0x75, 0x98, 0x69, 0x12, 0x2e, 0xec, 0x5d, 0xbb, 0xe1, 0x09, 0xbb, 0x1d, 0x58, 0x13, 0x8b, + 0xe9, 0xe5, 0x19, 0x0c, 0x52, 0x78, 0x6f, 0xcd, 0x13, 0x4f, 0x02, 0xb4, 0x0c, 0xb3, 0x0a, 0xe2, + 0x19, 0x90, 0xe3, 0x1f, 0x7a, 0xd6, 0x05, 0x05, 0x53, 0xb6, 0x5b, 0x12, 0x57, 0xf7, 0x0f, 0xbd, + 0x08, 0x49, 0x92, 0xc8, 0xc9, 0x18, 0x59, 0x8d, 0x90, 0x15, 0x98, 0x57, 0xc8, 0x86, 0xef, 0xed, + 0x26, 0xc1, 0x53, 0x0a, 0x5c, 0x94, 0xba, 0x35, 0xdf, 0xdb, 0x8d, 0xf0, 0x6b, 0x00, 0x5c, 0x10, + 0x26, 0xa8, 0x63, 0x13, 0x61, 0x65, 0xd4, 0x38, 0x17, 0x2a, 0x7a, 0x07, 0x55, 0xc2, 0x1d, 0x54, + 0x79, 0x1c, 0x6e, 0x31, 0x3d, 0xcc, 0x5f, 0x7f, 0x5e, 0x4e, 0xe3, 0xac, 0xb1, 0xab, 0x8a, 0xfb, + 0x13, 0x99, 0x74, 0x71, 0x6c, 0xe9, 0xf3, 0x1c, 0xcc, 0x3c, 0xa8, 0xae, 0x6d, 0x13, 0x46, 0x5a, + 0x54, 0x50, 0xc6, 0xd1, 0x9b, 0x90, 0x69, 0x91, 0x8e, 0x4d, 0x5d, 0x16, 0x58, 0xe9, 0xc5, 0xf4, + 0xf2, 0x58, 0x2d, 0xd7, 0xeb, 0x96, 0xa7, 0x1e, 0x90, 0xce, 0xfa, 0x06, 0xde, 0xc6, 0x53, 0x2d, + 0xd2, 0x59, 0x77, 0x59, 0x80, 0xde, 0x86, 0xd9, 0x76, 0xd0, 0x74, 0xbd, 0x7d, 0xdb, 0x39, 0xa4, + 0xcd, 0xa6, 0x2d, 0x77, 0xb4, 0x5a, 0xc8, 0x0c, 0x2e, 0x68, 0x45, 0x5d, 0xca, 0xa5, 0x17, 0xa8, + 0x02, 0x73, 0x72, 0x40, 0x83, 0xe8, 0x71, 0x85, 0x9e, 0x0d, 0x55, 0x31, 0x7e, 0x07, 0xe6, 0x88, + 0xc3, 0x6c, 0xb9, 0x73, 0x6c, 0x46, 0x04, 0xb5, 0x5d, 0xcf, 0xa1, 0x1d, 0xb5, 0x1a, 0xf9, 0xd5, + 0xd7, 0x06, 0x57, 0xb4, 0x4e, 0x04, 0xc1, 0x44, 0xd0, 0x0d, 0x09, 0xaa, 0xcd, 0xf7, 0xba, 0xe5, + 0x62, 0xb5, 0x8e, 0xfb, 0xa4, 0xb8, 0x48, 0x1c, 0xd6, 0x27, 0x41, 0xef, 0x01, 0x92, 0xdf, 0x10, + 0x1d, 0x3b, 0xf0, 0x0f, 0x29, 0x33, 0x9f, 0x50, 0x2b, 0x59, 0x9b, 0xeb, 0x75, 0xcb, 0x85, 0x6a, + 0x1d, 0x3f, 0xee, 0x6c, 0x4b, 0x9d, 0xa6, 0x28, 0x10, 0x87, 0x25, 0x05, 0xe8, 0x06, 0x4c, 0x4b, + 0x06, 0x6f, 0xc7, 0x16, 0x8c, 0x78, 0x5c, 0xaf, 0x6d, 0x2d, 0xdf, 0xeb, 0x96, 0xa1, 0x5a, 0xc7, + 0x5b, 0x3b, 0x8f, 0xa5, 0x14, 0x03, 0x71, 0x98, 0x79, 0x46, 0xb7, 0x60, 0x46, 0x5a, 0x90, 0xc6, + 0xbe, 0xdd, 0x74, 0x5b, 0xae, 0xd0, 0x2b, 0x5c, 0x2b, 0xf4, 0xba, 0xe5, 0x5c, 0xb5, 0x8e, 0xab, + 0x8d, 0xfd, 0x4d, 0x29, 0xc6, 0x39, 0xe2, 0xb0, 0xf0, 0x25, 0x69, 0xe4, 0xd0, 0x26, 0x39, 0x52, + 0x0b, 0xde, 0x67, 0x54, 0x97, 0xe2, 0xd0, 0x48, 0xbd, 0xa0, 0xdb, 0x90, 0x65, 0x9d, 0x9b, 0xc6, + 0x20, 0xab, 0xe6, 0xed, 0xf2, 0xe0, 0xbc, 0xe1, 0x8e, 0x36, 0xcc, 0xb0, 0xce, 0x4d, 0x6d, 0x75, + 0x1d, 0xe6, 0x95, 0x55, 0x34, 0xef, 0xfe, 0xee, 0x2e, 0xa7, 0xc2, 0x02, 0xb5, 0x11, 0x67, 0x25, + 0xce, 0xcc, 0xe1, 0x43, 0xa5, 0x40, 0x9b, 0x30, 0xc7, 0x3a, 0xab, 0x43, 0x0b, 0x95, 0x3b, 0xc3, + 0x42, 0xe1, 0x22, 0xeb, 0xac, 0xf6, 0x2f, 0xc9, 0x55, 0x98, 0x91, 0x6c, 0xbb, 0x8c, 0xfe, 0xbc, + 0x4d, 0xbd, 0xc6, 0x91, 0x35, 0xbd, 0x98, 0x5e, 0x9e, 0xc0, 0xd3, 0xac, 0xb3, 0x7a, 0x2f, 0x94, + 0xa1, 0x9f, 0xc0, 0x65, 0x46, 0x65, 0x58, 0x53, 0x7b, 0xc8, 0x0e, 0x28, 0x73, 0x7d, 0xc7, 0x6d, + 0xb8, 0xe2, 0xc8, 0x9a, 0x51, 0x9f, 0x5d, 0x1a, 0x1a, 0xa7, 0x82, 0xcb, 0x8d, 0xb5, 0xde, 0x09, + 0x7c, 0x8f, 0x7a, 0x02, 0x5f, 0x64, 0x91, 0x6c, 0x3b, 0x26, 0x40, 0xcf, 0xc1, 0x32, 0xdc, 0x0d, + 0xbf, 0xed, 0x89, 0x3e, 0xf2, 0xbc, 0x22, 0xbf, 0x3a, 0x9a, 0x7c, 0x4d, 0xc2, 0x23, 0xf6, 0x4b, + 0x2c, 0x16, 0x26, 0xe9, 0x37, 0x20, 0x2f, 0x8f, 0x96, 0xd3, 0x16, 0x47, 0x76, 0xe3, 0xa8, 0xd1, + 0xa4, 0x56, 0x61, 0x34, 0x69, 0x75, 0x6f, 0x8f, 0xd1, 0x3d, 0x22, 0xa8, 0x53, 0x6f, 0x8b, 0xa3, + 0x35, 0x09, 0xc5, 0xd3, 0x2d, 0xd2, 0x89, 0xde, 0x50, 0x15, 0x32, 0x8d, 0x17, 0xc4, 0xf3, 0x68, + 0x93, 0x5b, 0xc5, 0xc5, 0xf1, 0xe5, 0xdc, 0xea, 0x1b, 0x83, 0x24, 0x7d, 0xc7, 0xba, 0xb2, 0xa6, + 0xd1, 0x38, 0x32, 0x93, 0x87, 0x32, 0x70, 0xbd, 0x3d, 0x9b, 0x37, 0x7d, 0x91, 0x98, 0xf3, 0x59, + 0x35, 0xe7, 0xb3, 0x52, 0xf5, 0xa8, 0xe9, 0x8b, 0x78, 0xe2, 0x9f, 0xc1, 0x2b, 0x31, 0x7e, 0x70, + 0xc5, 0xd1, 0x59, 0x56, 0xfc, 0x62, 0x48, 0xda, 0xbf, 0xec, 0x6f, 0x41, 0x71, 0x87, 0x92, 0x86, + 0xef, 0x25, 0xbc, 0x98, 0x53, 0x5e, 0x14, 0xb4, 0x3c, 0xf2, 0x61, 0xe1, 0xbf, 0xc7, 0x60, 0xca, + 0x8c, 0x44, 0x9a, 0x99, 0x00, 0x14, 0x9b, 0xa5, 0xb5, 0x99, 0x96, 0xc7, 0xae, 0xaf, 0x00, 0x8a, + 0xe2, 0x4f, 0x0c, 0x1e, 0xd3, 0x23, 0x0d, 0x35, 0x31, 0x7c, 0x13, 0xe6, 0x5a, 0xae, 0x37, 0x34, + 0xc6, 0xf1, 0x33, 0xed, 0xea, 0x96, 0xeb, 0xf5, 0x0f, 0x4f, 0xb2, 0xc9, 0x55, 0xff, 0x0a, 0xc1, + 0x0c, 0x17, 0xe5, 0xa2, 0x0f, 0x9e, 0x11, 0xea, 0x91, 0x9d, 0x26, 0xb5, 0xf5, 0x20, 0x55, 0xc4, + 0xca, 0xe0, 0x69, 0x2d, 0x7c, 0xa2, 0x64, 0x77, 0x26, 0x3e, 0xf9, 0x6d, 0x39, 0xa5, 0xff, 0x2e, + 0xb5, 0x20, 0xbf, 0xee, 0x39, 0x75, 0x55, 0x82, 0xd5, 0x18, 0xf1, 0x1c, 0x74, 0x09, 0xc6, 0x5c, + 0x47, 0x4d, 0x55, 0xb6, 0x36, 0xd9, 0xeb, 0x96, 0xc7, 0x36, 0xea, 0x78, 0xcc, 0x75, 0x10, 0x82, + 0x09, 0x8f, 0x98, 0x20, 0x9e, 0xc5, 0xea, 0x19, 0xbd, 0x02, 0xe3, 0x6d, 0xd6, 0x54, 0x43, 0xcf, + 0xd6, 0xa6, 0x7a, 0xdd, 0xf2, 0xf8, 0x13, 0xbc, 0x89, 0xa5, 0x0c, 0xcd, 0xc3, 0x85, 0xa6, 0xbf, + 0xe7, 0x73, 0x6b, 0x62, 0x71, 0x7c, 0x39, 0x8b, 0xf5, 0xcb, 0x92, 0x93, 0xf8, 0xdc, 0x03, 0xdf, + 0xa1, 0x4d, 0x99, 0x50, 0x76, 0xe4, 0x77, 0xed, 0xe8, 0xa3, 0x2a, 0xa1, 0x28, 0x5f, 0x36, 0xea, + 0x78, 0x4a, 0x29, 0x37, 0x42, 0xb7, 0xc6, 0x4e, 0x74, 0x6b, 0x3c, 0x76, 0x6b, 0xe9, 0xdf, 0xc6, + 0xe0, 0xd5, 0xe8, 0x33, 0x4f, 0x29, 0x93, 0x19, 0x7d, 0x23, 0xae, 0x87, 0xd0, 0xc3, 0xa1, 0x6f, + 0xde, 0x4e, 0x7c, 0xb3, 0xf7, 0x79, 0xf9, 0x0d, 0x78, 0xfd, 0xa3, 0x9f, 0x92, 0x95, 0x7f, 0xb8, + 0xb1, 0xf2, 0xfd, 0xe7, 0xcb, 0x77, 0xef, 0xfc, 0x74, 0xe5, 0xf9, 0xdd, 0xf0, 0xf5, 0xad, 0x7f, + 0x5c, 0x7d, 0xe7, 0x9f, 0xaf, 0xfd, 0xd3, 0x47, 0xd7, 0x3a, 0x6f, 0xc4, 0xce, 0x3d, 0x84, 0x4c, + 0x4b, 0x8e, 0xc6, 0x8e, 0x5c, 0x54, 0x84, 0x6a, 0x84, 0xe7, 0x22, 0x54, 0x2c, 0x1b, 0x8e, 0xdc, + 0xbd, 0x2f, 0x08, 0x73, 0x0e, 0x09, 0xa3, 0xf6, 0x81, 0x1e, 0x80, 0x19, 0x61, 0x21, 0x94, 0x9b, + 0x71, 0x49, 0xe8, 0xae, 0xcb, 0x5a, 0x7d, 0xd0, 0x09, 0x0d, 0x0d, 0xe5, 0x06, 0xba, 0xf4, 0xaf, + 0x53, 0x50, 0x1c, 0x9c, 0x17, 0xf4, 0x3e, 0x8c, 0xbb, 0x0e, 0x57, 0xf3, 0x90, 0x5b, 0xfd, 0xf6, + 0xe0, 0x86, 0x3b, 0x65, 0x1a, 0x13, 0xf5, 0x91, 0x64, 0x40, 0xcf, 0xa0, 0x60, 0x0c, 0x23, 0x3f, + 0xc6, 0xd4, 0x2e, 0x5e, 0x18, 0x11, 0x7b, 0x0c, 0x5d, 0x0d, 0xf5, 0xba, 0xe5, 0xfc, 0xa6, 0x8f, + 0xc9, 0xb3, 0xea, 0x96, 0x91, 0xe1, 0xbc, 0x81, 0x86, 0x1e, 0x12, 0x98, 0x0b, 0x89, 0x83, 0x17, + 0x47, 0x7d, 0xf3, 0x31, 0x82, 0x7c, 0xfb, 0x83, 0x0f, 0x43, 0xf2, 0x8b, 0xbd, 0x6e, 0x79, 0xd6, + 0x90, 0xc7, 0x62, 0x3c, 0x6b, 0xd0, 0xdb, 0x2f, 0x8e, 0xc2, 0x4f, 0xdc, 0x85, 0xd9, 0xe8, 0xe4, + 0xdb, 0x41, 0x93, 0x78, 0x72, 0x25, 0xd5, 0x2c, 0xea, 0x6c, 0x1f, 0x9d, 0xfe, 0xed, 0x26, 0xf1, + 0x36, 0xea, 0xb8, 0xb0, 0xdb, 0x27, 0x90, 0xdb, 0x73, 0x32, 0x78, 0xe1, 0x0b, 0x9f, 0x5b, 0x17, + 0xd4, 0x7e, 0x37, 0x6f, 0x68, 0x19, 0x8a, 0xbc, 0x1d, 0x04, 0x3e, 0x13, 0xdc, 0x6e, 0x34, 0x09, + 0xe7, 0xf6, 0x8e, 0xaa, 0x04, 0x32, 0x38, 0x1f, 0xca, 0xd7, 0xa4, 0xb8, 0x36, 0x02, 0xd9, 0x50, + 0x05, 0xc0, 0x20, 0x72, 0x0d, 0xb5, 0xe0, 0x92, 0x43, 0x77, 0x49, 0xbb, 0x29, 0xec, 0x16, 0x69, + 0xd8, 0x41, 0x14, 0xc6, 0x4d, 0xb1, 0xf7, 0xda, 0xa9, 0xb1, 0xbe, 0x66, 0xf5, 0xba, 0xe5, 0xf9, + 0xba, 0x26, 0xe8, 0xd3, 0xe0, 0x79, 0x43, 0xfb, 0x80, 0x34, 0x12, 0x25, 0xdf, 0x55, 0x98, 0x91, + 0xf1, 0x2e, 0x8e, 0x8c, 0x59, 0x9d, 0x77, 0x5b, 0x6e, 0x1c, 0x7a, 0x15, 0x88, 0x74, 0x12, 0x20, + 0x30, 0x20, 0xd2, 0x89, 0x41, 0x8b, 0x30, 0xcd, 0x28, 0xa7, 0x82, 0xeb, 0x32, 0x56, 0x15, 0x02, + 0x19, 0x0c, 0x5a, 0x26, 0xeb, 0x57, 0xf4, 0x03, 0x98, 0x6d, 0x73, 0xca, 0xed, 0x5b, 0xab, 0xf6, + 0x8e, 0x6b, 0x2a, 0x6d, 0x95, 0xe7, 0x33, 0xb5, 0xd9, 0x5e, 0xb7, 0x3c, 0xf3, 0x84, 0x53, 0x7e, + 0x6b, 0xb5, 0xe6, 0xaa, 0x7a, 0x1b, 0xcf, 0xb4, 0x93, 0xaf, 0xd2, 0x87, 0x68, 0x06, 0x65, 0x86, + 0x55, 0x19, 0x3f, 0x83, 0xa7, 0x43, 0xe1, 0x7d, 0xdf, 0xf5, 0xd0, 0x3b, 0x80, 0x8c, 0x0f, 0x2a, + 0x93, 0x7b, 0xbe, 0xd7, 0xa0, 0x5c, 0xa5, 0xef, 0x0c, 0x2e, 0x6a, 0x8d, 0xc4, 0x6d, 0x29, 0x39, + 0x7a, 0x0e, 0x28, 0x9c, 0xea, 0x5d, 0x9f, 0xb5, 0x88, 0x50, 0xd3, 0x5c, 0x50, 0xd3, 0xbc, 0x3c, + 0x34, 0xcd, 0xba, 0xe1, 0xd9, 0x26, 0x47, 0x4d, 0x9f, 0x38, 0xf7, 0x22, 0x7c, 0x6d, 0x42, 0x1e, + 0x14, 0x3c, 0x6b, 0x98, 0x62, 0x85, 0x89, 0xc1, 0x9f, 0x4d, 0x42, 0xee, 0x41, 0x75, 0xed, 0x11, + 0x15, 0x42, 0xf6, 0x34, 0xe8, 0x2e, 0x4c, 0xb5, 0x39, 0xb5, 0x89, 0xc3, 0xcc, 0xa9, 0x1c, 0xae, + 0xde, 0x6b, 0xbe, 0xdf, 0x7c, 0x4a, 0x9a, 0x6d, 0x5a, 0x83, 0x5e, 0xb7, 0x3c, 0xf9, 0x84, 0xd3, + 0x6a, 0x1d, 0xe3, 0xc9, 0x36, 0xa7, 0x55, 0x87, 0xa1, 0xfb, 0x20, 0xcb, 0x4a, 0xbb, 0x45, 0xd8, + 0x9e, 0xab, 0x0f, 0x61, 0x6e, 0xf5, 0xca, 0x10, 0xc7, 0x93, 0x0d, 0x4f, 0xdc, 0x5a, 0xd5, 0x2c, + 0x33, 0xbd, 0x6e, 0x39, 0x5b, 0xad, 0xe3, 0x07, 0xca, 0x04, 0x67, 0x89, 0xc3, 0xf4, 0x23, 0x7a, + 0x1f, 0x0a, 0x66, 0xdf, 0xaa, 0x8a, 0xca, 0x6f, 0x0b, 0xd3, 0x3a, 0xbd, 0x32, 0x44, 0x58, 0x37, + 0x5d, 0x71, 0x6d, 0xe2, 0x37, 0xb2, 0x9b, 0x98, 0x51, 0x76, 0xb5, 0xc7, 0xda, 0x2a, 0x26, 0x6a, + 0x44, 0x44, 0x13, 0xe7, 0x21, 0x5a, 0x0b, 0x89, 0x9e, 0xc1, 0x65, 0x2e, 0x88, 0x68, 0xf3, 0xe1, + 0x12, 0xef, 0xc2, 0xd9, 0x08, 0x2f, 0x6a, 0xfb, 0xc1, 0xfa, 0xee, 0x29, 0x58, 0x86, 0x78, 0xb8, + 0xbe, 0x9b, 0xfc, 0xf2, 0x49, 0xc4, 0x97, 0xb4, 0xf5, 0x50, 0x61, 0xb7, 0x9e, 0xac, 0xb6, 0xa7, + 0x4e, 0xd8, 0x3b, 0xf1, 0xfa, 0x87, 0x95, 0xb7, 0x26, 0x8d, 0xcb, 0xef, 0xe7, 0xa3, 0xab, 0x69, + 0x7d, 0xe6, 0x2b, 0xa7, 0x11, 0xf6, 0xd5, 0x08, 0x9a, 0x76, 0xb8, 0xbc, 0xae, 0x0e, 0x96, 0xd7, + 0xd9, 0x53, 0x86, 0xfc, 0x9d, 0xdb, 0x9a, 0xa6, 0xaf, 0xf8, 0x5e, 0xf8, 0x11, 0x4c, 0x27, 0x7d, + 0x47, 0x2b, 0x70, 0xe1, 0x40, 0x3e, 0xa8, 0x6d, 0x7c, 0x4a, 0x8b, 0xa1, 0x51, 0x0b, 0x1b, 0x80, + 0x86, 0x3d, 0x45, 0xb7, 0xfa, 0x49, 0xbe, 0xa4, 0x24, 0xd2, 0xd8, 0xa5, 0xff, 0xca, 0x42, 0x46, + 0xce, 0x80, 0x20, 0x82, 0x22, 0x0c, 0xa8, 0xd1, 0x66, 0x8c, 0xca, 0x25, 0x8d, 0x63, 0x65, 0xfa, + 0x2c, 0xb1, 0xd2, 0x9c, 0x5c, 0x63, 0x9e, 0x08, 0x8a, 0x58, 0x06, 0x06, 0xee, 0x32, 0xea, 0x24, + 0x39, 0xc7, 0xce, 0xc1, 0x69, 0xcc, 0x13, 0x9c, 0xdf, 0x83, 0x69, 0x7d, 0x17, 0xa6, 0xe3, 0xbf, + 0x49, 0x70, 0x17, 0x07, 0xd9, 0x54, 0x16, 0xc0, 0x39, 0x0d, 0x55, 0x2f, 0xa3, 0x52, 0xef, 0xc4, + 0xff, 0x4b, 0xea, 0x7d, 0x0e, 0x0b, 0xd1, 0xdd, 0x83, 0xcb, 0x5a, 0xd4, 0xb1, 0xa3, 0x4a, 0x99, + 0x08, 0x73, 0xdc, 0x4e, 0xbb, 0x5b, 0x98, 0x50, 0xf7, 0x0a, 0x97, 0xc3, 0x3b, 0x0a, 0x45, 0x51, + 0x37, 0x0c, 0x55, 0x81, 0xde, 0x05, 0x4b, 0xd1, 0x3b, 0xf4, 0xc0, 0x36, 0x47, 0x2f, 0xba, 0x5c, + 0xd1, 0x77, 0x21, 0x73, 0x52, 0x5f, 0xa7, 0x07, 0x8f, 0x94, 0xd6, 0xdc, 0xb2, 0x60, 0xb8, 0x18, + 0xf7, 0x1a, 0xc9, 0x53, 0x3a, 0xa5, 0x06, 0x5d, 0x1a, 0x2a, 0x09, 0x4c, 0x63, 0xa1, 0x0f, 0x25, + 0x9e, 0x0b, 0xfa, 0xde, 0xf5, 0x21, 0xa5, 0x70, 0x25, 0xa0, 0x9e, 0x23, 0x69, 0x49, 0x10, 0x34, + 0xdd, 0x86, 0x0a, 0x18, 0xd1, 0x70, 0xcd, 0x31, 0x1b, 0xee, 0xc5, 0x62, 0x6c, 0x38, 0x2e, 0xbc, + 0x60, 0x88, 0x46, 0xe8, 0xd0, 0x3a, 0x14, 0x7f, 0xde, 0xa6, 0x6d, 0xea, 0xd8, 0x8c, 0xf2, 0xc0, + 0xf7, 0x38, 0xe5, 0x56, 0x56, 0x75, 0x68, 0xa3, 0x96, 0x6a, 0xcd, 0x6f, 0xb5, 0x88, 0xe7, 0xe0, + 0x82, 0xb6, 0xc1, 0xa1, 0x89, 0xa4, 0x09, 0xbd, 0x55, 0xa7, 0x8f, 0x0b, 0x6e, 0xc1, 0x97, 0xd3, + 0x18, 0x1b, 0x6c, 0x4c, 0xd0, 0xdf, 0x01, 0x32, 0xde, 0xa8, 0x64, 0x48, 0x1a, 0x0d, 0x1a, 0xe8, + 0xb4, 0x3c, 0x62, 0xa8, 0xe1, 0x79, 0xaa, 0xc8, 0xfc, 0x58, 0x55, 0x50, 0x6c, 0x06, 0x13, 0x4b, + 0xd0, 0x03, 0x98, 0x0f, 0x3d, 0x53, 0x9c, 0xc6, 0x3d, 0x95, 0xc4, 0x47, 0xdc, 0xb7, 0x49, 0x4b, + 0xe3, 0x0e, 0x46, 0xc6, 0x30, 0x21, 0x43, 0x37, 0x60, 0x9e, 0x75, 0xec, 0x43, 0xd7, 0x73, 0xfc, + 0x43, 0x6e, 0x93, 0x03, 0xe2, 0x36, 0x65, 0x27, 0x63, 0x52, 0x3b, 0x62, 0x9d, 0x67, 0x5a, 0x55, + 0x0d, 0x35, 0x0b, 0xff, 0x99, 0x06, 0x48, 0xf8, 0xb3, 0x04, 0x53, 0x81, 0x4e, 0xc8, 0xea, 0xc4, + 0x4f, 0xd7, 0x32, 0xbd, 0xcf, 0xcb, 0x13, 0x41, 0xae, 0xf3, 0x1a, 0x0e, 0x15, 0xe8, 0x07, 0x30, + 0x15, 0xba, 0x39, 0xf6, 0xa5, 0x6e, 0x9a, 0xf3, 0x1b, 0x5a, 0xa0, 0x77, 0xcf, 0x7e, 0xa1, 0xa8, + 0x2d, 0x15, 0xdc, 0xa4, 0xfe, 0x7f, 0xb1, 0x20, 0x1b, 0x95, 0xd8, 0xe8, 0xbd, 0x64, 0x29, 0x7e, + 0xed, 0xc4, 0x52, 0xfc, 0x94, 0x1a, 0x7c, 0x0d, 0xa0, 0xc1, 0x28, 0x31, 0x77, 0x7f, 0x63, 0xe7, + 0xb9, 0xfb, 0x33, 0x76, 0x55, 0x21, 0x49, 0xda, 0x81, 0x13, 0x92, 0x8c, 0x9f, 0x87, 0xc4, 0xd8, + 0x55, 0x45, 0xd4, 0x97, 0x4d, 0x24, 0xda, 0xc5, 0x45, 0xc8, 0x39, 0x94, 0x37, 0x98, 0x1b, 0xc8, + 0x33, 0xa1, 0xc2, 0x47, 0x16, 0x27, 0x45, 0x68, 0x03, 0x80, 0x08, 0xc1, 0xdc, 0x9d, 0xb6, 0xa0, + 0xdc, 0x9a, 0x54, 0x3b, 0xfa, 0xad, 0x13, 0x27, 0xa2, 0x52, 0x8d, 0xb0, 0xeb, 0x9e, 0x60, 0x47, + 0x38, 0x61, 0x8c, 0x7e, 0x06, 0x39, 0x13, 0x0b, 0x6d, 0x39, 0xa9, 0x53, 0xe7, 0xef, 0x6f, 0xd4, + 0x5d, 0x5d, 0x28, 0xaf, 0x73, 0x0c, 0x07, 0x21, 0x86, 0xa3, 0x1a, 0x20, 0x4e, 0x99, 0x0a, 0xd6, + 0x01, 0xf3, 0x77, 0xdd, 0x26, 0x95, 0x1d, 0x43, 0x46, 0x75, 0x0c, 0xea, 0x8e, 0xf1, 0x91, 0xd6, + 0x6e, 0x6b, 0xe5, 0x46, 0x1d, 0x17, 0x79, 0xbf, 0xc4, 0x41, 0xb7, 0xe1, 0x92, 0xb9, 0xbe, 0xb6, + 0xa5, 0x8e, 0x32, 0x75, 0xdd, 0x4d, 0x39, 0x57, 0xa9, 0x37, 0x8b, 0xe7, 0x8d, 0xf6, 0x91, 0x52, + 0x56, 0xb5, 0x0e, 0xfd, 0x10, 0x16, 0x92, 0x01, 0x6a, 0xc0, 0x12, 0x94, 0xa5, 0x95, 0x40, 0xf4, + 0x5b, 0x57, 0x60, 0x4e, 0x1d, 0xcb, 0x01, 0xb3, 0x9c, 0x32, 0x9b, 0x95, 0xaa, 0x7e, 0xfc, 0x3d, + 0xc8, 0x36, 0x7d, 0x4d, 0xc4, 0xad, 0x69, 0xb5, 0x1e, 0xcb, 0x27, 0xaf, 0xc7, 0x66, 0x08, 0xd5, + 0xcb, 0x11, 0x9b, 0x8e, 0xec, 0x83, 0x66, 0xce, 0xdc, 0x07, 0xe5, 0x47, 0xf6, 0x41, 0x23, 0xb2, + 0x5e, 0xe1, 0x9b, 0x6c, 0x38, 0x8b, 0xdf, 0x74, 0xc3, 0x39, 0x7b, 0x8e, 0x86, 0xf3, 0xe4, 0x26, + 0x10, 0xfd, 0x4d, 0x9a, 0xc0, 0xb9, 0xb3, 0x34, 0x81, 0xf3, 0x67, 0x68, 0x02, 0x2f, 0x9e, 0xad, + 0x09, 0xbc, 0xf4, 0x55, 0x9b, 0xc0, 0xcb, 0x67, 0x6e, 0x02, 0xad, 0x13, 0x9a, 0xc0, 0x77, 0x21, + 0xcb, 0x7c, 0x5f, 0xd8, 0x2a, 0xcc, 0xbf, 0xa2, 0x66, 0xd7, 0x1a, 0x2a, 0x65, 0x7d, 0x5f, 0xc8, + 0x18, 0x8f, 0x33, 0xcc, 0x3c, 0xa1, 0xa7, 0x30, 0xe9, 0x51, 0x21, 0xd7, 0x75, 0x41, 0x25, 0x9e, + 0xbb, 0x7f, 0xea, 0x96, 0x57, 0xcf, 0xf5, 0xe3, 0xd5, 0x16, 0x15, 0x1b, 0xf5, 0x5e, 0xb7, 0x7c, + 0x41, 0x3d, 0xe0, 0x0b, 0x1e, 0x15, 0xea, 0xb2, 0x69, 0x5a, 0xae, 0x38, 0x37, 0xd5, 0xbd, 0xf5, + 0xea, 0xe8, 0xc4, 0x93, 0x68, 0x00, 0xf4, 0xaf, 0x01, 0x09, 0x01, 0xce, 0xb5, 0x48, 0x23, 0xea, + 0x37, 0xd7, 0x20, 0xab, 0x08, 0x65, 0x72, 0xb7, 0xae, 0x8c, 0x1e, 0x5f, 0x98, 0xfc, 0x6b, 0xd3, + 0xbd, 0x6e, 0x39, 0x2a, 0xad, 0x71, 0x46, 0xf2, 0xa8, 0x22, 0xfb, 0x26, 0x4c, 0x71, 0x9d, 0xea, + 0xac, 0xd7, 0x14, 0xc5, 0xe5, 0x13, 0x32, 0x21, 0x0e, 0x71, 0xe8, 0x3d, 0x08, 0x0b, 0x12, 0x3b, + 0x34, 0x2d, 0x9d, 0x6e, 0x9a, 0x37, 0xf8, 0xf0, 0x57, 0xc2, 0x6b, 0x90, 0x8f, 0xea, 0x47, 0xb5, + 0x88, 0x56, 0x59, 0x55, 0x8d, 0xd3, 0xa6, 0x6a, 0x54, 0x0b, 0x88, 0xde, 0x84, 0x42, 0x9b, 0x53, + 0x27, 0x46, 0x71, 0x6b, 0x71, 0x71, 0x7c, 0x79, 0x46, 0x6d, 0x1d, 0x27, 0x84, 0x71, 0x89, 0x53, + 0x6c, 0xf1, 0x9e, 0xb0, 0x5e, 0x8f, 0x7f, 0x90, 0x8b, 0x36, 0x04, 0xfa, 0xae, 0xc1, 0xb1, 0x8f, + 0x4d, 0xa3, 0x78, 0xc3, 0x5a, 0x52, 0x3f, 0xba, 0x14, 0x7b, 0xdd, 0xf2, 0xf4, 0x26, 0xe1, 0x02, + 0xdf, 0x57, 0x4d, 0xe0, 0x0d, 0xed, 0x08, 0xfe, 0x58, 0xbf, 0x0d, 0x1b, 0xde, 0xb4, 0xae, 0x8e, + 0x34, 0xbc, 0xd9, 0x67, 0x78, 0x13, 0x7d, 0x04, 0xaf, 0x0e, 0xd6, 0xc9, 0x8c, 0x36, 0xa8, 0x7b, + 0xa0, 0x53, 0xf4, 0xb5, 0xf3, 0xd4, 0xe1, 0x51, 0x31, 0x8d, 0x0d, 0x43, 0x55, 0x9e, 0xb8, 0x9c, + 0xfe, 0x99, 0x4b, 0xef, 0x81, 0x37, 0x4e, 0x08, 0x74, 0x12, 0xa2, 0xd7, 0x1d, 0x82, 0xe8, 0x19, + 0xad, 0x00, 0xda, 0x51, 0xf7, 0x19, 0x47, 0xb2, 0x16, 0x6f, 0x50, 0x4f, 0x90, 0x3d, 0x6a, 0xbd, + 0xb9, 0x98, 0x5e, 0x1e, 0xc3, 0xb3, 0x46, 0xb3, 0x1d, 0x29, 0xd0, 0xb7, 0xa0, 0x10, 0xf5, 0x10, + 0xe6, 0x86, 0xe2, 0x5b, 0x8b, 0xe9, 0xe5, 0x0b, 0x38, 0x1f, 0x8a, 0xcd, 0xcd, 0x03, 0x91, 0x87, + 0x54, 0x5a, 0xd9, 0xc4, 0x61, 0xe6, 0x3e, 0x9b, 0x5b, 0xcb, 0x2a, 0x07, 0x0d, 0x45, 0x37, 0x7d, + 0xb5, 0x6d, 0x6e, 0x60, 0x74, 0x06, 0xc6, 0xca, 0xb8, 0x5a, 0xc7, 0x5a, 0xc7, 0xe5, 0xc9, 0x56, + 0x12, 0x87, 0x19, 0x09, 0xaa, 0x43, 0xde, 0x7c, 0x22, 0xa4, 0x7f, 0xeb, 0x0c, 0xf4, 0x78, 0x46, + 0x1b, 0x85, 0x2c, 0xf7, 0xc1, 0x30, 0x47, 0xdd, 0x02, 0xb7, 0xde, 0x56, 0x3c, 0xe5, 0xa1, 0x66, + 0x35, 0x1c, 0xa2, 0x61, 0x2a, 0x68, 0xc3, 0x50, 0xcc, 0x65, 0x1b, 0x62, 0x2a, 0xf2, 0x51, 0x5d, + 0x08, 0xb7, 0xbe, 0xad, 0x78, 0xcf, 0xd6, 0x86, 0x68, 0xa2, 0x11, 0x2a, 0x8e, 0x3e, 0x00, 0x48, + 0xdc, 0x67, 0xbd, 0x73, 0xbe, 0xfb, 0x2c, 0x9c, 0xb0, 0x45, 0x04, 0xf2, 0x01, 0xf3, 0x0f, 0x5c, + 0x79, 0x1e, 0x29, 0x93, 0xd1, 0x6e, 0x45, 0x65, 0xb1, 0x3b, 0x32, 0x52, 0x6f, 0xc7, 0x9a, 0xf3, + 0x5c, 0x83, 0xcf, 0x24, 0x18, 0x37, 0x1c, 0x54, 0x87, 0xd9, 0x48, 0x20, 0x83, 0x85, 0x43, 0x04, + 0xb1, 0x2a, 0x26, 0x52, 0x0c, 0xee, 0xf9, 0x47, 0xea, 0x1f, 0x2b, 0x70, 0x31, 0x69, 0x51, 0x27, + 0x82, 0x2c, 0xfc, 0x08, 0x0a, 0x03, 0xe5, 0x22, 0x2a, 0xc2, 0xf8, 0x3e, 0xd5, 0x3f, 0x0b, 0x65, + 0xb1, 0x7c, 0x44, 0xf3, 0xe1, 0x65, 0x83, 0xfe, 0x95, 0x43, 0xbf, 0xdc, 0x19, 0xfb, 0x5e, 0x7a, + 0xe1, 0x29, 0xe4, 0xfb, 0xab, 0x9b, 0x11, 0xd6, 0x95, 0xa4, 0xf5, 0x88, 0x20, 0x1a, 0x12, 0x24, + 0x78, 0x4d, 0x1f, 0xf0, 0x01, 0x40, 0x54, 0x45, 0x71, 0x74, 0x07, 0x72, 0xf1, 0x3f, 0xc6, 0xc8, + 0x7e, 0x60, 0x5c, 0xdd, 0x6a, 0x9d, 0x54, 0x76, 0x61, 0xa0, 0x91, 0xed, 0xd2, 0xcf, 0xe0, 0xd2, + 0x9a, 0xaa, 0xe4, 0x63, 0xb5, 0x69, 0x54, 0x6a, 0x00, 0x31, 0xab, 0x69, 0x32, 0x4e, 0x26, 0x4d, + 0x74, 0x16, 0xd9, 0x88, 0x7e, 0xe9, 0xdf, 0xd3, 0x70, 0xe9, 0x89, 0xaa, 0xf1, 0xbf, 0x09, 0x7a, + 0x74, 0x17, 0x20, 0xfe, 0xd7, 0x99, 0x13, 0xdb, 0x97, 0x7b, 0x12, 0xf2, 0x80, 0xf0, 0x7d, 0xd3, + 0x50, 0x65, 0x77, 0x43, 0xc1, 0xd2, 0xff, 0xa4, 0x61, 0xee, 0x7d, 0x2a, 0x86, 0x9c, 0x7b, 0x0c, + 0xf9, 0xd8, 0x39, 0xfb, 0xab, 0x37, 0x59, 0xd3, 0x34, 0xd6, 0xf3, 0xaf, 0xef, 0xee, 0xff, 0xa6, + 0xe1, 0xe2, 0xa6, 0xcb, 0x63, 0x7f, 0x79, 0xe8, 0xf0, 0x87, 0x50, 0x48, 0x06, 0x80, 0xd8, 0xe3, + 0x37, 0x4f, 0x39, 0xfa, 0xa3, 0x7d, 0xce, 0x93, 0x24, 0xe2, 0xeb, 0x7b, 0x2d, 0x0f, 0x89, 0xcf, + 0x1c, 0xca, 0xcc, 0x2f, 0x52, 0xfa, 0x45, 0xfd, 0xe0, 0xa7, 0xfe, 0x6b, 0x41, 0xff, 0x57, 0x8c, + 0x7e, 0x91, 0x6d, 0x60, 0x20, 0xd3, 0x81, 0xfe, 0x1f, 0x18, 0xf5, 0xbc, 0xf4, 0xab, 0x34, 0xcc, + 0x3d, 0x1a, 0xb1, 0x48, 0xdf, 0x85, 0xc9, 0xb3, 0xee, 0x1e, 0xed, 0x93, 0x81, 0x7f, 0xed, 0x11, + 0xbd, 0x7d, 0x0f, 0x20, 0x4e, 0x6e, 0x68, 0x16, 0x66, 0xb6, 0x1f, 0x3e, 0x5b, 0xc7, 0xf6, 0x93, + 0xad, 0x1f, 0x6f, 0x3d, 0x7c, 0xb6, 0x55, 0x4c, 0xc5, 0xa2, 0x5a, 0xf5, 0xf1, 0xe3, 0x75, 0xfc, + 0x61, 0x31, 0x8d, 0x10, 0xe4, 0xb5, 0x68, 0xfd, 0xef, 0x1f, 0xaf, 0xe3, 0xad, 0xea, 0x66, 0x71, + 0xac, 0xf6, 0x1f, 0xe9, 0x4f, 0x5f, 0x96, 0xd2, 0x9f, 0xbd, 0x2c, 0xa5, 0xff, 0xf8, 0xb2, 0x94, + 0xfa, 0xf3, 0xcb, 0x52, 0xea, 0x2f, 0x2f, 0x4b, 0xa9, 0xbf, 0xbe, 0x2c, 0xa5, 0xbe, 0x78, 0x59, + 0x4a, 0xff, 0xa2, 0x57, 0x4a, 0xff, 0xb2, 0x57, 0x4a, 0xfd, 0xae, 0x57, 0x4a, 0xff, 0xbe, 0x57, + 0x4a, 0x7d, 0xd2, 0x2b, 0xa5, 0xfe, 0xd0, 0x2b, 0xa5, 0x3e, 0xed, 0x95, 0xd2, 0x9f, 0xf5, 0x4a, + 0xe9, 0x3f, 0xf6, 0x4a, 0xa9, 0x3f, 0xf7, 0x4a, 0xe9, 0xbf, 0xf4, 0x4a, 0xa9, 0xbf, 0xf6, 0x4a, + 0xe9, 0x2f, 0x7a, 0xa5, 0xd4, 0x2f, 0x8e, 0x4b, 0xa9, 0x5f, 0x1e, 0x97, 0xd2, 0xbf, 0x3e, 0x2e, + 0xa5, 0x7e, 0x73, 0x5c, 0x4a, 0xff, 0xf6, 0xb8, 0x94, 0xfa, 0xdd, 0x71, 0x29, 0xf5, 0xfb, 0xe3, + 0x52, 0xfa, 0x93, 0xe3, 0x52, 0xfa, 0x0f, 0xc7, 0xa5, 0xf4, 0x4f, 0xde, 0x39, 0x6b, 0x55, 0x29, + 0xbc, 0x60, 0x67, 0x67, 0x52, 0xcd, 0xc8, 0xad, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x17, 0x83, + 0x1b, 0x5f, 0x8f, 0x27, 0x00, 0x00, } diff --git a/pkg/ttnpb/end_device.validator.pb.go b/pkg/ttnpb/end_device.validator.pb.go index a9c7a38426..85d4ed05e1 100644 --- a/pkg/ttnpb/end_device.validator.pb.go +++ b/pkg/ttnpb/end_device.validator.pb.go @@ -87,14 +87,35 @@ func (this *EndDeviceVersion) Validate() error { return nil } func (this *MACSettings) Validate() error { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(&(this.ClassBTimeout)); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("ClassBTimeout", err) + if this.UseADR != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.UseADR); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("UseADR", err) + } } - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(&(this.ClassCTimeout)); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("ClassCTimeout", err) + if this.ADRMargin != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.ADRMargin); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("ADRMargin", err) + } } - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(&(this.StatusTimePeriodicity)); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("StatusTimePeriodicity", err) + if this.ClassBTimeout != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.ClassBTimeout); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("ClassBTimeout", err) + } + } + if this.ClassCTimeout != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.ClassCTimeout); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("ClassCTimeout", err) + } + } + if this.StatusTimePeriodicity != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.StatusTimePeriodicity); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("StatusTimePeriodicity", err) + } + } + if this.StatusCountPeriodicity != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.StatusCountPeriodicity); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("StatusCountPeriodicity", err) + } } if this.Rx1Delay != nil { if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Rx1Delay); err != nil { From d3e6c340fdcb679b94ba60ac85f76b77978237a5 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 8 Feb 2019 19:23:44 +0100 Subject: [PATCH 06/40] ns: Make MACSettings optional, add defaults --- cmd/ttn-lw-cli/commands/end_devices.go | 6 - pkg/networkserver/adr.go | 16 +- pkg/networkserver/adr_test.go | 7 +- pkg/networkserver/config.go | 3 + pkg/networkserver/downlink.go | 31 +- pkg/networkserver/downlink_internal_test.go | 445 +++++++++++++++--- pkg/networkserver/errors.go | 1 - pkg/networkserver/grpc_deviceregistry.go | 37 +- pkg/networkserver/grpc_deviceregistry_test.go | 21 +- pkg/networkserver/grpc_gsns.go | 23 +- pkg/networkserver/grpc_gsns_test.go | 11 +- pkg/networkserver/mac_dev_status.go | 28 +- pkg/networkserver/mac_reset.go | 4 +- pkg/networkserver/mac_reset_test.go | 12 +- pkg/networkserver/networkserver.go | 10 +- pkg/networkserver/networkserver_util_test.go | 5 +- pkg/networkserver/utils.go | 35 +- pkg/networkserver/utils_internal_test.go | 2 +- 18 files changed, 508 insertions(+), 189 deletions(-) diff --git a/cmd/ttn-lw-cli/commands/end_devices.go b/cmd/ttn-lw-cli/commands/end_devices.go index 5eac064ccf..01a236b0ce 100644 --- a/cmd/ttn-lw-cli/commands/end_devices.go +++ b/cmd/ttn-lw-cli/commands/end_devices.go @@ -238,15 +238,9 @@ var ( device.ApplicationServerAddress = config.ApplicationServerAddress device.JoinServerAddress = config.JoinServerAddress device.Uses32BitFCnt = true - device.MACSettings = &ttnpb.MACSettings{ - UseADR: true, - ADRMargin: 15, - } paths = append(paths, "application_server_address", "join_server_address", - "mac_settings.adr_margin", - "mac_settings.use_adr", "network_server_address", "resets_f_cnt", "resets_join_nonces", diff --git a/pkg/networkserver/adr.go b/pkg/networkserver/adr.go index fe7302ef0a..290ebf0a32 100644 --- a/pkg/networkserver/adr.go +++ b/pkg/networkserver/adr.go @@ -72,7 +72,10 @@ const maxNbTrans = 3 // optimalADRUplinkCount is the amount of uplinks required to ensure optimal results from the ADR algorithm. const optimalADRUplinkCount = 20 -func adaptDataRate(dev *ttnpb.EndDevice, fps *frequencyplans.Store) error { +// DefaultADRMargin is the default ADR margin used if not specified in MACSettings of the device or NS-wide defaults. +const DefaultADRMargin = 15 + +func adaptDataRate(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults ttnpb.MACSettings) error { ups := dev.RecentADRUplinks if len(ups) == 0 { return nil @@ -111,7 +114,16 @@ func adaptDataRate(dev *ttnpb.EndDevice, fps *frequencyplans.Store) error { // minimum (floor) that we need to demodulate the signal. We subtract a // configurable margin, and an extra safety margin if we're afraid that we // don't have enough data for our decision. - margin := maxSNR - df - float32(dev.MACSettings.ADRMargin) + margin := maxSNR - df + + if dev.MACSettings != nil && dev.MACSettings.ADRMargin != nil { + margin -= dev.MACSettings.ADRMargin.Value + } else if defaults.ADRMargin != nil { + margin -= defaults.ADRMargin.Value + } else { + margin -= DefaultADRMargin + } + if len(ups) < optimalADRUplinkCount { margin -= safetyMargin } diff --git a/pkg/networkserver/adr_test.go b/pkg/networkserver/adr_test.go index 4fe5ebf8c5..06cd5211ee 100644 --- a/pkg/networkserver/adr_test.go +++ b/pkg/networkserver/adr_test.go @@ -19,6 +19,7 @@ import ( "math/rand" "testing" + pbtypes "github.com/gogo/protobuf/types" "github.com/smartystreets/assertions" "go.thethings.network/lorawan-stack/pkg/frequencyplans" "go.thethings.network/lorawan-stack/pkg/ttnpb" @@ -104,7 +105,9 @@ func TestAdaptDataRate(t *testing.T) { }, }, MACSettings: &ttnpb.MACSettings{ - ADRMargin: 2, + ADRMargin: &pbtypes.FloatValue{ + Value: 2, + }, }, FrequencyPlanID: test.EUFrequencyPlanID, RecentADRUplinks: adrMatrixToUplinks([]adrMatrixRow{ @@ -154,7 +157,7 @@ func TestAdaptDataRate(t *testing.T) { dev := CopyEndDevice(tc.Device) - err := adaptDataRate(dev, frequencyplans.NewStore(test.FrequencyPlansFetcher)) + err := adaptDataRate(dev, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{}) if err != nil && !a.So(err, should.Equal, tc.Error) || err == nil && !a.So(err, should.BeNil) { t.FailNow() diff --git a/pkg/networkserver/config.go b/pkg/networkserver/config.go index ec1b5026a0..35bbcaf6c5 100644 --- a/pkg/networkserver/config.go +++ b/pkg/networkserver/config.go @@ -19,6 +19,7 @@ import ( "go.thethings.network/lorawan-stack/pkg/errors" "go.thethings.network/lorawan-stack/pkg/ttnpb" + "go.thethings.network/lorawan-stack/pkg/types" ) // Config represents the NetworkServer configuration. @@ -28,6 +29,8 @@ type Config struct { DeduplicationWindow time.Duration `name:"deduplication-window" description:"Time window during which, duplicate messages are collected for metadata"` CooldownWindow time.Duration `name:"cooldown-window" description:"Time window starting right after deduplication window, during which, duplicate messages are discarded"` DownlinkPriorities DownlinkPriorityConfig `name:"downlink-priorities" description:"Downlink message priorities"` + NetID types.NetID `name:"net_id" description:"NetID of this Network Server"` + DefaultMACSettings ttnpb.MACSettings `name:"mac_defaults" description:"Default MAC settings to use if not specified for device"` } // DownlinkPriorityConfig defines priorities for downlink messages. diff --git a/pkg/networkserver/downlink.go b/pkg/networkserver/downlink.go index e1c6d22aad..7ae85d449c 100644 --- a/pkg/networkserver/downlink.go +++ b/pkg/networkserver/downlink.go @@ -49,6 +49,18 @@ type DownlinkTaskQueue interface { var errNoDownlink = errors.Define("no_downlink", "no downlink to send") +const DefaultClassCTimeout = 15 * time.Second + +func deviceClassCTimeout(dev *ttnpb.EndDevice, defaults ttnpb.MACSettings) time.Duration { + ret := DefaultClassCTimeout + if dev.MACSettings != nil && dev.MACSettings.ClassCTimeout != nil { + ret = *dev.MACSettings.ClassCTimeout + } else if defaults.ClassCTimeout != nil { + ret = *defaults.ClassCTimeout + } + return ret +} + // generateDownlink attempts to generate a downlink. // generateDownlink returns the marshaled payload of the downlink, application downlink, if included in the payload and error, if any. // generateDownlink may mutate the device in order to record the downlink generated. @@ -60,7 +72,7 @@ var errNoDownlink = errors.Define("no_downlink", "no downlink to send") // For example, a sequence of 'NewChannel' MAC commands could be generated for a // device operating in a region where a fixed channel plan is defined in case // dev.MACState.CurrentParameters.Channels is not equal to dev.MACState.DesiredParameters.Channels. -func generateDownlink(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, maxUpLen uint16, fps *frequencyplans.Store) ([]byte, *ttnpb.ApplicationDownlink, error) { +func generateDownlink(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, maxUpLen uint16, fps *frequencyplans.Store, defaults ttnpb.MACSettings) ([]byte, *ttnpb.ApplicationDownlink, error) { if dev.MACState == nil { return nil, nil, errUnknownMACState } @@ -105,7 +117,9 @@ func generateDownlink(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, max enqueueNewChannelReq, enqueueDutyCycleReq, enqueueRxParamSetupReq, - enqueueDevStatusReq, + func(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen uint16, maxUpLen uint16) (uint16, uint16, bool) { + return enqueueDevStatusReq(ctx, dev, maxDownLen, maxUpLen, defaults) + }, enqueueRxTimingSetupReq, enqueuePingSlotChannelReq, enqueueBeaconFreqReq, @@ -237,11 +251,11 @@ outer: logger = logger.WithField("f_pending", pld.FHDR.FCtrl.FPending) switch { - case dev.MACState.DeviceClass != ttnpb.CLASS_C, - mType != ttnpb.MType_CONFIRMED_DOWN && len(dev.MACState.PendingRequests) == 0: + case mType != ttnpb.MType_CONFIRMED_DOWN && len(dev.MACState.PendingRequests) == 0: break - case dev.MACState.LastConfirmedDownlinkAt != nil && dev.MACState.LastConfirmedDownlinkAt.Add(dev.MACSettings.ClassCTimeout).After(time.Now()): + case dev.MACState.DeviceClass == ttnpb.CLASS_C && + dev.MACState.LastConfirmedDownlinkAt.Add(deviceClassCTimeout(dev, defaults)).After(time.Now()): return nil, nil, errScheduleTooSoon default: @@ -594,6 +608,7 @@ func (ns *NetworkServer) processDownlinkTask(ctx context.Context) error { band.DataRates[minDR].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), maxUpLength, ns.FrequencyPlans, + ns.defaultMACSettings, ) if err != nil { return nil, nil, err @@ -648,16 +663,17 @@ func (ns *NetworkServer) processDownlinkTask(ctx context.Context) error { band.DataRates[req.Rx1DataRateIndex].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), maxUpLength, ns.FrequencyPlans, + ns.defaultMACSettings, ) if err != nil { if errors.Resemble(err, errScheduleTooSoon) { - nextDownlinkAt = dev.MACState.LastConfirmedDownlinkAt.Add(dev.MACSettings.ClassCTimeout) + nextDownlinkAt = dev.MACState.LastConfirmedDownlinkAt.Add(deviceClassCTimeout(dev, ns.defaultMACSettings)) } return nil, nil, err } if dev.MACState.DeviceClass == ttnpb.CLASS_C { if dev.MACState.LastConfirmedDownlinkAt != nil { - nextDownlinkAt = dev.MACState.LastConfirmedDownlinkAt.Add(dev.MACSettings.ClassCTimeout) + nextDownlinkAt = dev.MACState.LastConfirmedDownlinkAt.Add(deviceClassCTimeout(dev, ns.defaultMACSettings)) } else { nextDownlinkAt = time.Now() } @@ -742,6 +758,7 @@ func (ns *NetworkServer) processDownlinkTask(ctx context.Context) error { band.DataRates[req.Rx2DataRateIndex].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), maxUpLength, ns.FrequencyPlans, + ns.defaultMACSettings, ) if err != nil { return nil, nil, err diff --git a/pkg/networkserver/downlink_internal_test.go b/pkg/networkserver/downlink_internal_test.go index 155e8a576a..a48461361e 100644 --- a/pkg/networkserver/downlink_internal_test.go +++ b/pkg/networkserver/downlink_internal_test.go @@ -24,6 +24,7 @@ import ( "testing" "time" + pbtypes "github.com/gogo/protobuf/types" "github.com/mohae/deepcopy" "github.com/smartystreets/assertions" "go.thethings.network/lorawan-stack/pkg/band" @@ -147,8 +148,7 @@ func TestProcessDownlinkTask(t *testing.T) { }, }, }, - LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - LastDevStatusReceivedAt: TimePtr(time.Now().Add(time.Hour)), + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, MACState: &ttnpb.MACState{ CurrentParameters: ttnpb.MACParameters{ Rx1Delay: ttnpb.RX_DELAY_3, @@ -168,7 +168,6 @@ func TestProcessDownlinkTask(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, RxWindowsAvailable: true, }, - MACSettings: &ttnpb.MACSettings{}, RecentUplinks: []*ttnpb.UplinkMessage{ ttnpb.NewPopulatedUplinkMessage(test.Randy, false), ttnpb.NewPopulatedUplinkMessage(test.Randy, false), @@ -310,6 +309,7 @@ func TestProcessDownlinkTask(t *testing.T) { band.DataRates[ttnpb.DATA_RATE_1].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), ns.FrequencyPlans, + ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx2 payload: %s", err) @@ -385,6 +385,7 @@ func TestProcessDownlinkTask(t *testing.T) { band.DataRates[drIdx].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), ns.FrequencyPlans, + ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx2 payload: %s", err) @@ -575,8 +576,7 @@ func TestProcessDownlinkTask(t *testing.T) { }, }, }, - LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - LastDevStatusReceivedAt: TimePtr(time.Now().Add(time.Hour)), + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, MACState: &ttnpb.MACState{ CurrentParameters: ttnpb.MACParameters{ Rx1Delay: ttnpb.RX_DELAY_3, @@ -596,7 +596,6 @@ func TestProcessDownlinkTask(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, RxWindowsAvailable: true, }, - MACSettings: &ttnpb.MACSettings{}, RecentUplinks: []*ttnpb.UplinkMessage{ ttnpb.NewPopulatedUplinkMessage(test.Randy, false), ttnpb.NewPopulatedUplinkMessage(test.Randy, false), @@ -738,6 +737,7 @@ func TestProcessDownlinkTask(t *testing.T) { band.DataRates[rx1DRIdx].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), ns.FrequencyPlans, + ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx1 payload: %s", err) @@ -809,6 +809,7 @@ func TestProcessDownlinkTask(t *testing.T) { band.DataRates[rx1DRIdx].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), ns.FrequencyPlans, + ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx1 payload: %s", err) @@ -992,8 +993,7 @@ func TestProcessDownlinkTask(t *testing.T) { }, }, }, - LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - LastDevStatusReceivedAt: TimePtr(time.Now().Add(time.Hour)), + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, MACState: &ttnpb.MACState{ CurrentParameters: ttnpb.MACParameters{ Rx1Delay: ttnpb.RX_DELAY_3, @@ -1013,7 +1013,6 @@ func TestProcessDownlinkTask(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, RxWindowsAvailable: true, }, - MACSettings: &ttnpb.MACSettings{}, RecentUplinks: []*ttnpb.UplinkMessage{ ttnpb.NewPopulatedUplinkMessage(test.Randy, false), ttnpb.NewPopulatedUplinkMessage(test.Randy, false), @@ -1153,6 +1152,7 @@ func TestProcessDownlinkTask(t *testing.T) { band.DataRates[ttnpb.DATA_RATE_1].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), ns.FrequencyPlans, + ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx2 payload: %s", err) @@ -1226,6 +1226,7 @@ func TestProcessDownlinkTask(t *testing.T) { band.DataRates[rx1DRIdx].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), ns.FrequencyPlans, + ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx1 payload: %s", err) @@ -1234,6 +1235,7 @@ func TestProcessDownlinkTask(t *testing.T) { band.DataRates[ttnpb.DATA_RATE_1].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), ns.FrequencyPlans, + ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx2 payload: %s", err) @@ -1550,8 +1552,7 @@ func TestProcessDownlinkTask(t *testing.T) { }, }, }, - LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - LastDevStatusReceivedAt: TimePtr(time.Now().Add(time.Hour)), + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, MACState: &ttnpb.MACState{ CurrentParameters: ttnpb.MACParameters{ Rx1Delay: ttnpb.RX_DELAY_3, @@ -1571,7 +1572,6 @@ func TestProcessDownlinkTask(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, RxWindowsAvailable: true, }, - MACSettings: &ttnpb.MACSettings{}, RecentUplinks: []*ttnpb.UplinkMessage{ ttnpb.NewPopulatedUplinkMessage(test.Randy, false), ttnpb.NewPopulatedUplinkMessage(test.Randy, false), @@ -1735,6 +1735,7 @@ func TestProcessDownlinkTask(t *testing.T) { band.DataRates[ttnpb.DATA_RATE_1].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), ns.FrequencyPlans, + ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx2 payload: %s", err) @@ -1811,6 +1812,7 @@ func TestProcessDownlinkTask(t *testing.T) { band.DataRates[rx1DRIdx].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), ns.FrequencyPlans, + ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx1 payload: %s", err) @@ -1819,6 +1821,7 @@ func TestProcessDownlinkTask(t *testing.T) { band.DataRates[ttnpb.DATA_RATE_1].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), ns.FrequencyPlans, + ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx2 payload: %s", err) @@ -2159,8 +2162,7 @@ func TestProcessDownlinkTask(t *testing.T) { }, }, }, - LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - LastDevStatusReceivedAt: TimePtr(time.Now().Add(time.Hour)), + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, MACState: &ttnpb.MACState{ CurrentParameters: ttnpb.MACParameters{ Rx1DataRateOffset: 2, @@ -2181,7 +2183,6 @@ func TestProcessDownlinkTask(t *testing.T) { Payload: []byte("testJoinAccept"), }, }, - MACSettings: &ttnpb.MACSettings{}, RecentUplinks: []*ttnpb.UplinkMessage{ ttnpb.NewPopulatedUplinkMessage(test.Randy, false), ttnpb.NewPopulatedUplinkMessage(test.Randy, false), @@ -2547,6 +2548,10 @@ func TestProcessDownlinkTask(t *testing.T) { Devices: &MockDeviceRegistry{ SetByIDFunc: tc.SetByIDFunc, }, + DefaultMACSettings: ttnpb.MACSettings{ + StatusTimePeriodicity: DurationPtr(0), + StatusCountPeriodicity: &pbtypes.UInt32Value{Value: 0}, + }, }, )).(*NetworkServer) ns.FrequencyPlans = frequencyplans.NewStore(test.FrequencyPlansFetcher) @@ -2640,12 +2645,13 @@ func TestGenerateDownlink(t *testing.T) { } for _, tc := range []struct { - Name string - Device *ttnpb.EndDevice - Context context.Context - Bytes []byte - Error error - DeviceDiff func(*ttnpb.EndDevice) + Name string + Device *ttnpb.EndDevice + Context context.Context + Bytes []byte + ApplicationDownlinkAssertion func(t *testing.T, down *ttnpb.ApplicationDownlink) bool + DeviceAssertion func(*testing.T, *ttnpb.EndDevice) bool + Error error }{ { Name: "1.1/no app downlink/no MAC/no ack", @@ -2656,13 +2662,11 @@ func TestGenerateDownlink(t *testing.T) { DeviceID: DeviceID, DevAddr: &DevAddr, }, - MACSettings: &ttnpb.MACSettings{}, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_1, }, - Session: ttnpb.NewPopulatedSession(test.Randy, false), - LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - LastDevStatusReceivedAt: TimePtr(time.Unix(42, 0)), + Session: ttnpb.NewPopulatedSession(test.Randy, false), + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, RecentUplinks: []*ttnpb.UplinkMessage{{ Payload: &ttnpb.Message{ MHDR: ttnpb.MHDR{ @@ -2684,7 +2688,7 @@ func TestGenerateDownlink(t *testing.T) { DevAddr: &DevAddr, }, MACSettings: &ttnpb.MACSettings{ - StatusCountPeriodicity: 3, + StatusCountPeriodicity: &pbtypes.UInt32Value{Value: 3}, }, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_1, @@ -2716,7 +2720,7 @@ func TestGenerateDownlink(t *testing.T) { DevAddr: &DevAddr, }, MACSettings: &ttnpb.MACSettings{ - StatusTimePeriodicity: 24 * time.Hour, + StatusTimePeriodicity: DurationPtr(24 * time.Hour), }, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_1, @@ -2744,7 +2748,6 @@ func TestGenerateDownlink(t *testing.T) { DeviceID: DeviceID, DevAddr: &DevAddr, }, - MACSettings: &ttnpb.MACSettings{}, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_1, }, @@ -2759,8 +2762,7 @@ func TestGenerateDownlink(t *testing.T) { }, }, }, - LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - LastDevStatusReceivedAt: TimePtr(time.Unix(42, 0)), + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, RecentUplinks: []*ttnpb.UplinkMessage{{ Payload: &ttnpb.Message{ MHDR: ttnpb.MHDR{ @@ -2793,8 +2795,43 @@ func TestGenerateDownlink(t *testing.T) { }, }, }, ttnpb.MAC_V1_1, 24), - DeviceDiff: func(dev *ttnpb.EndDevice) { - dev.Session.LastNFCntDown++ + DeviceAssertion: func(t *testing.T, dev *ttnpb.EndDevice) bool { + return assertions.New(t).So(dev, should.Resemble, &ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: ApplicationID}, + DeviceID: DeviceID, + DevAddr: &DevAddr, + }, + MACState: &ttnpb.MACState{ + LoRaWANVersion: ttnpb.MAC_V1_1, + }, + Session: &ttnpb.Session{ + LastNFCntDown: 42, + SessionKeys: ttnpb.SessionKeys{ + NwkSEncKey: &ttnpb.KeyEnvelope{ + Key: NwkSEncKey[:], + }, + SNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: SNwkSIntKey[:], + }, + }, + }, + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, + RecentUplinks: []*ttnpb.UplinkMessage{{ + Payload: &ttnpb.Message{ + MHDR: ttnpb.MHDR{ + MType: ttnpb.MType_CONFIRMED_UP, + }, + Payload: &ttnpb.Message_MACPayload{ + MACPayload: &ttnpb.MACPayload{ + FHDR: ttnpb.FHDR{ + FCnt: 24, + }, + }, + }, + }, + }}, + }) }, }, { @@ -2806,7 +2843,6 @@ func TestGenerateDownlink(t *testing.T) { DeviceID: DeviceID, DevAddr: &DevAddr, }, - MACSettings: &ttnpb.MACSettings{}, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_1, }, @@ -2828,8 +2864,7 @@ func TestGenerateDownlink(t *testing.T) { FRMPayload: []byte("test"), }, }, - LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - LastDevStatusReceivedAt: TimePtr(time.Unix(42, 0)), + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, RecentUplinks: []*ttnpb.UplinkMessage{{ Payload: &ttnpb.Message{ MHDR: ttnpb.MHDR{ @@ -2858,9 +2893,45 @@ func TestGenerateDownlink(t *testing.T) { }, }, }, ttnpb.MAC_V1_1, 0), - DeviceDiff: func(dev *ttnpb.EndDevice) { - i := len(dev.QueuedApplicationDownlinks) - 1 - dev.QueuedApplicationDownlinks = dev.QueuedApplicationDownlinks[:i] + ApplicationDownlinkAssertion: func(t *testing.T, down *ttnpb.ApplicationDownlink) bool { + return assertions.New(t).So(down, should.Resemble, &ttnpb.ApplicationDownlink{ + Confirmed: false, + FCnt: 42, + FPort: 1, + FRMPayload: []byte("test"), + }) + }, + DeviceAssertion: func(t *testing.T, dev *ttnpb.EndDevice) bool { + return assertions.New(t).So(dev, should.Resemble, &ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: ApplicationID}, + DeviceID: DeviceID, + DevAddr: &DevAddr, + }, + MACState: &ttnpb.MACState{ + LoRaWANVersion: ttnpb.MAC_V1_1, + }, + Session: &ttnpb.Session{ + SessionKeys: ttnpb.SessionKeys{ + NwkSEncKey: &ttnpb.KeyEnvelope{ + Key: NwkSEncKey[:], + }, + SNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: SNwkSIntKey[:], + }, + }, + }, + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, + RecentUplinks: []*ttnpb.UplinkMessage{{ + Payload: &ttnpb.Message{ + MHDR: ttnpb.MHDR{ + MType: ttnpb.MType_UNCONFIRMED_UP, + }, + Payload: &ttnpb.Message_MACPayload{MACPayload: &ttnpb.MACPayload{}}, + }, + }}, + QueuedApplicationDownlinks: []*ttnpb.ApplicationDownlink{}, + }) }, }, { @@ -2872,7 +2943,6 @@ func TestGenerateDownlink(t *testing.T) { DeviceID: DeviceID, DevAddr: &DevAddr, }, - MACSettings: &ttnpb.MACSettings{}, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_1, }, @@ -2894,8 +2964,7 @@ func TestGenerateDownlink(t *testing.T) { FRMPayload: []byte("test"), }, }, - LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - LastDevStatusReceivedAt: TimePtr(time.Unix(42, 0)), + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, RecentUplinks: []*ttnpb.UplinkMessage{{ Payload: &ttnpb.Message{ MHDR: ttnpb.MHDR{ @@ -2930,9 +2999,51 @@ func TestGenerateDownlink(t *testing.T) { }, }, }, ttnpb.MAC_V1_1, 24), - DeviceDiff: func(dev *ttnpb.EndDevice) { - i := len(dev.QueuedApplicationDownlinks) - 1 - dev.QueuedApplicationDownlinks = dev.QueuedApplicationDownlinks[:i] + ApplicationDownlinkAssertion: func(t *testing.T, down *ttnpb.ApplicationDownlink) bool { + return assertions.New(t).So(down, should.Resemble, &ttnpb.ApplicationDownlink{ + Confirmed: false, + FCnt: 42, + FPort: 1, + FRMPayload: []byte("test"), + }) + }, + DeviceAssertion: func(t *testing.T, dev *ttnpb.EndDevice) bool { + return assertions.New(t).So(dev, should.Resemble, &ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: ApplicationID}, + DeviceID: DeviceID, + DevAddr: &DevAddr, + }, + MACState: &ttnpb.MACState{ + LoRaWANVersion: ttnpb.MAC_V1_1, + }, + Session: &ttnpb.Session{ + SessionKeys: ttnpb.SessionKeys{ + NwkSEncKey: &ttnpb.KeyEnvelope{ + Key: NwkSEncKey[:], + }, + SNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: SNwkSIntKey[:], + }, + }, + }, + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, + RecentUplinks: []*ttnpb.UplinkMessage{{ + Payload: &ttnpb.Message{ + MHDR: ttnpb.MHDR{ + MType: ttnpb.MType_CONFIRMED_UP, + }, + Payload: &ttnpb.Message_MACPayload{ + MACPayload: &ttnpb.MACPayload{ + FHDR: ttnpb.FHDR{ + FCnt: 24, + }, + }, + }, + }, + }}, + QueuedApplicationDownlinks: []*ttnpb.ApplicationDownlink{}, + }) }, }, { @@ -2944,7 +3055,6 @@ func TestGenerateDownlink(t *testing.T) { DeviceID: DeviceID, DevAddr: &DevAddr, }, - MACSettings: &ttnpb.MACSettings{}, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_1, }, @@ -2966,8 +3076,7 @@ func TestGenerateDownlink(t *testing.T) { FRMPayload: []byte("test"), }, }, - LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - LastDevStatusReceivedAt: TimePtr(time.Unix(42, 0)), + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, RecentUplinks: []*ttnpb.UplinkMessage{{ Payload: &ttnpb.Message{ MHDR: ttnpb.MHDR{ @@ -2996,10 +3105,59 @@ func TestGenerateDownlink(t *testing.T) { }, }, }, ttnpb.MAC_V1_1, 0), - DeviceDiff: func(dev *ttnpb.EndDevice) { - i := len(dev.QueuedApplicationDownlinks) - 1 - dev.QueuedApplicationDownlinks, dev.MACState.PendingApplicationDownlink = dev.QueuedApplicationDownlinks[:i], dev.QueuedApplicationDownlinks[i] - dev.Session.LastConfFCntDown = 42 + ApplicationDownlinkAssertion: func(t *testing.T, down *ttnpb.ApplicationDownlink) bool { + return assertions.New(t).So(down, should.Resemble, &ttnpb.ApplicationDownlink{ + Confirmed: true, + FCnt: 42, + FPort: 1, + FRMPayload: []byte("test"), + }) + }, + DeviceAssertion: func(t *testing.T, dev *ttnpb.EndDevice) bool { + a := assertions.New(t) + if !a.So(dev.MACState, should.NotBeNil) || !a.So(dev.MACState.LastConfirmedDownlinkAt, should.NotBeNil) { + t.FailNow() + } + now := time.Now() + a.So([]time.Time{now.Add(-time.Minute), *dev.MACState.LastConfirmedDownlinkAt, now}, should.BeChronological) + return a.So(dev, should.Resemble, &ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: ApplicationID}, + DeviceID: DeviceID, + DevAddr: &DevAddr, + }, + MACState: &ttnpb.MACState{ + LoRaWANVersion: ttnpb.MAC_V1_1, + LastConfirmedDownlinkAt: dev.MACState.LastConfirmedDownlinkAt, + PendingApplicationDownlink: &ttnpb.ApplicationDownlink{ + Confirmed: true, + FCnt: 42, + FPort: 1, + FRMPayload: []byte("test"), + }, + }, + Session: &ttnpb.Session{ + LastConfFCntDown: 42, + SessionKeys: ttnpb.SessionKeys{ + NwkSEncKey: &ttnpb.KeyEnvelope{ + Key: NwkSEncKey[:], + }, + SNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: SNwkSIntKey[:], + }, + }, + }, + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, + RecentUplinks: []*ttnpb.UplinkMessage{{ + Payload: &ttnpb.Message{ + MHDR: ttnpb.MHDR{ + MType: ttnpb.MType_UNCONFIRMED_UP, + }, + Payload: &ttnpb.Message_MACPayload{MACPayload: &ttnpb.MACPayload{}}, + }, + }}, + QueuedApplicationDownlinks: []*ttnpb.ApplicationDownlink{}, + }) }, }, { @@ -3011,7 +3169,6 @@ func TestGenerateDownlink(t *testing.T) { DeviceID: DeviceID, DevAddr: &DevAddr, }, - MACSettings: &ttnpb.MACSettings{}, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_1, }, @@ -3025,6 +3182,7 @@ func TestGenerateDownlink(t *testing.T) { }, }, }, + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, QueuedApplicationDownlinks: []*ttnpb.ApplicationDownlink{ { Confirmed: true, @@ -3033,8 +3191,6 @@ func TestGenerateDownlink(t *testing.T) { FRMPayload: []byte("test"), }, }, - LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - LastDevStatusReceivedAt: TimePtr(time.Unix(42, 0)), RecentUplinks: []*ttnpb.UplinkMessage{{ Payload: &ttnpb.Message{ MHDR: ttnpb.MHDR{ @@ -3069,10 +3225,65 @@ func TestGenerateDownlink(t *testing.T) { }, }, }, ttnpb.MAC_V1_1, 24), - DeviceDiff: func(dev *ttnpb.EndDevice) { - i := len(dev.QueuedApplicationDownlinks) - 1 - dev.QueuedApplicationDownlinks, dev.MACState.PendingApplicationDownlink = dev.QueuedApplicationDownlinks[:i], dev.QueuedApplicationDownlinks[i] - dev.Session.LastConfFCntDown = 42 + ApplicationDownlinkAssertion: func(t *testing.T, down *ttnpb.ApplicationDownlink) bool { + return assertions.New(t).So(down, should.Resemble, &ttnpb.ApplicationDownlink{ + Confirmed: true, + FCnt: 42, + FPort: 1, + FRMPayload: []byte("test"), + }) + }, + DeviceAssertion: func(t *testing.T, dev *ttnpb.EndDevice) bool { + a := assertions.New(t) + if !a.So(dev.MACState, should.NotBeNil) || !a.So(dev.MACState.LastConfirmedDownlinkAt, should.NotBeNil) { + t.FailNow() + } + now := time.Now() + a.So([]time.Time{now.Add(-time.Minute), *dev.MACState.LastConfirmedDownlinkAt, now}, should.BeChronological) + return a.So(dev, should.Resemble, &ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: ApplicationID}, + DeviceID: DeviceID, + DevAddr: &DevAddr, + }, + MACState: &ttnpb.MACState{ + LoRaWANVersion: ttnpb.MAC_V1_1, + LastConfirmedDownlinkAt: dev.MACState.LastConfirmedDownlinkAt, + PendingApplicationDownlink: &ttnpb.ApplicationDownlink{ + Confirmed: true, + FCnt: 42, + FPort: 1, + FRMPayload: []byte("test"), + }, + }, + Session: &ttnpb.Session{ + LastConfFCntDown: 42, + SessionKeys: ttnpb.SessionKeys{ + NwkSEncKey: &ttnpb.KeyEnvelope{ + Key: NwkSEncKey[:], + }, + SNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: SNwkSIntKey[:], + }, + }, + }, + LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, + QueuedApplicationDownlinks: []*ttnpb.ApplicationDownlink{}, + RecentUplinks: []*ttnpb.UplinkMessage{{ + Payload: &ttnpb.Message{ + MHDR: ttnpb.MHDR{ + MType: ttnpb.MType_CONFIRMED_UP, + }, + Payload: &ttnpb.Message_MACPayload{ + MACPayload: &ttnpb.MACPayload{ + FHDR: ttnpb.FHDR{ + FCnt: 24, + }, + }, + }, + }, + }}, + }) }, }, { @@ -3085,11 +3296,11 @@ func TestGenerateDownlink(t *testing.T) { DevAddr: &DevAddr, }, MACSettings: &ttnpb.MACSettings{ - StatusCountPeriodicity: 3, + StatusCountPeriodicity: &pbtypes.UInt32Value{Value: 3}, }, MACState: &ttnpb.MACState{ - LastDevStatusFCntUp: 4, LoRaWANVersion: ttnpb.MAC_V1_1, + LastDevStatusFCntUp: 4, }, Session: &ttnpb.Session{ LastFCntUp: 99, @@ -3133,11 +3344,51 @@ func TestGenerateDownlink(t *testing.T) { }, }, }, ttnpb.MAC_V1_1, 0), - DeviceDiff: func(dev *ttnpb.EndDevice) { - dev.MACState.PendingRequests = []*ttnpb.MACCommand{ - ttnpb.CID_DEV_STATUS.MACCommand(), + DeviceAssertion: func(t *testing.T, dev *ttnpb.EndDevice) bool { + a := assertions.New(t) + if !a.So(dev.MACState, should.NotBeNil) || !a.So(dev.MACState.LastConfirmedDownlinkAt, should.NotBeNil) { + t.FailNow() } - dev.Session.LastNFCntDown++ + now := time.Now() + a.So([]time.Time{now.Add(-time.Minute), *dev.MACState.LastConfirmedDownlinkAt, now}, should.BeChronological) + return a.So(dev, should.Resemble, &ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: ApplicationID}, + DeviceID: DeviceID, + DevAddr: &DevAddr, + }, + MACSettings: &ttnpb.MACSettings{ + StatusCountPeriodicity: &pbtypes.UInt32Value{Value: 3}, + }, + MACState: &ttnpb.MACState{ + LoRaWANVersion: ttnpb.MAC_V1_1, + LastConfirmedDownlinkAt: dev.MACState.LastConfirmedDownlinkAt, + LastDevStatusFCntUp: 4, + PendingRequests: []*ttnpb.MACCommand{ + ttnpb.CID_DEV_STATUS.MACCommand(), + }, + }, + Session: &ttnpb.Session{ + LastFCntUp: 99, + LastNFCntDown: 42, + SessionKeys: ttnpb.SessionKeys{ + NwkSEncKey: &ttnpb.KeyEnvelope{ + Key: NwkSEncKey[:], + }, + SNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: SNwkSIntKey[:], + }, + }, + }, + RecentUplinks: []*ttnpb.UplinkMessage{{ + Payload: &ttnpb.Message{ + MHDR: ttnpb.MHDR{ + MType: ttnpb.MType_UNCONFIRMED_UP, + }, + Payload: &ttnpb.Message_MACPayload{MACPayload: &ttnpb.MACPayload{}}, + }, + }}, + }) }, }, { @@ -3150,7 +3401,7 @@ func TestGenerateDownlink(t *testing.T) { DevAddr: &DevAddr, }, MACSettings: &ttnpb.MACSettings{ - StatusTimePeriodicity: time.Nanosecond, + StatusTimePeriodicity: DurationPtr(time.Nanosecond), }, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_1, @@ -3196,11 +3447,49 @@ func TestGenerateDownlink(t *testing.T) { }, }, }, ttnpb.MAC_V1_1, 0), - DeviceDiff: func(dev *ttnpb.EndDevice) { - dev.MACState.PendingRequests = []*ttnpb.MACCommand{ - ttnpb.CID_DEV_STATUS.MACCommand(), + DeviceAssertion: func(t *testing.T, dev *ttnpb.EndDevice) bool { + a := assertions.New(t) + if !a.So(dev.MACState, should.NotBeNil) || !a.So(dev.MACState.LastConfirmedDownlinkAt, should.NotBeNil) { + t.FailNow() } - dev.Session.LastNFCntDown++ + now := time.Now() + a.So([]time.Time{now.Add(-time.Minute), *dev.MACState.LastConfirmedDownlinkAt, now}, should.BeChronological) + return a.So(dev, should.Resemble, &ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: ApplicationID}, + DeviceID: DeviceID, + DevAddr: &DevAddr, + }, + MACSettings: &ttnpb.MACSettings{ + StatusTimePeriodicity: DurationPtr(time.Nanosecond), + }, + MACState: &ttnpb.MACState{ + LoRaWANVersion: ttnpb.MAC_V1_1, + LastConfirmedDownlinkAt: dev.MACState.LastConfirmedDownlinkAt, + PendingRequests: []*ttnpb.MACCommand{ + ttnpb.CID_DEV_STATUS.MACCommand(), + }, + }, + Session: &ttnpb.Session{ + LastNFCntDown: 42, + SessionKeys: ttnpb.SessionKeys{ + NwkSEncKey: &ttnpb.KeyEnvelope{ + Key: NwkSEncKey[:], + }, + SNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: SNwkSIntKey[:], + }, + }, + }, + RecentUplinks: []*ttnpb.UplinkMessage{{ + Payload: &ttnpb.Message{ + MHDR: ttnpb.MHDR{ + MType: ttnpb.MType_UNCONFIRMED_UP, + }, + Payload: &ttnpb.Message_MACPayload{MACPayload: &ttnpb.MACPayload{}}, + }, + }}, + }) }, }, } { @@ -3209,19 +3498,27 @@ func TestGenerateDownlink(t *testing.T) { dev := CopyEndDevice(tc.Device) - b, _, err := generateDownlink(tc.Context, dev, math.MaxUint16, math.MaxUint16, frequencyplans.NewStore(test.FrequencyPlansFetcher)) + b, appDown, err := generateDownlink(tc.Context, dev, math.MaxUint16, math.MaxUint16, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{ + StatusTimePeriodicity: DurationPtr(0), + StatusCountPeriodicity: &pbtypes.UInt32Value{Value: 0}, + }) if tc.Error != nil && !a.So(err, should.EqualErrorOrDefinition, tc.Error) || tc.Error == nil && !a.So(err, should.BeNil) { t.FailNow() } a.So(b, should.Resemble, tc.Bytes) + if tc.ApplicationDownlinkAssertion != nil { + a.So(tc.ApplicationDownlinkAssertion(t, appDown), should.BeTrue) + } else { + a.So(appDown, should.BeNil) + } - expected := CopyEndDevice(tc.Device) - if tc.DeviceDiff != nil { - tc.DeviceDiff(expected) + if tc.DeviceAssertion != nil { + a.So(tc.DeviceAssertion(t, dev), should.BeTrue) + } else { + a.So(dev, should.Resemble, tc.Device) } - a.So(dev, should.Resemble, expected) }) } } diff --git a/pkg/networkserver/errors.go b/pkg/networkserver/errors.go index 3006548e8c..52521affc7 100644 --- a/pkg/networkserver/errors.go +++ b/pkg/networkserver/errors.go @@ -50,7 +50,6 @@ var ( errJoinServerNotFound = errors.DefineNotFound("join_server_not_found", "Join Server not found") errMACRequestNotFound = errors.DefineInvalidArgument("mac_request_not_found", "MAC response received, but corresponding request not found") errNoFrequencyPlan = errors.DefineInvalidArgument("no_frequency_plan", "no frequency plan specified") - errNoMACSettings = errors.DefineInvalidArgument("no_mac_settings", "no mac settings specified") errNoPath = errors.DefineNotFound("no_downlink_path", "no downlink path available") errNoPayload = errors.DefineInvalidArgument("no_payload", "no message payload specified") errNoRekey = errors.DefineInvalidArgument("no_rekey", "rekey not received after join-accept") diff --git a/pkg/networkserver/grpc_deviceregistry.go b/pkg/networkserver/grpc_deviceregistry.go index 661ca8a5ac..dcd04c21b4 100644 --- a/pkg/networkserver/grpc_deviceregistry.go +++ b/pkg/networkserver/grpc_deviceregistry.go @@ -62,45 +62,26 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest "frequency_plan_id", "lorawan_phy_version", "lorawan_version", - "mac_settings.use_adr", - "resets_f_cnt", - "resets_join_nonces", - "supports_class_b", - "supports_class_c", "supports_join", - "uses_32_bit_f_cnt", ); err != nil { return nil, nil, errInvalidFieldMask.WithCause(err) } - if req.Device.MACSettings == nil { - return nil, nil, errNoMACSettings - } - - if !ttnpb.HasAnyField(paths, "mac_settings.adr_margin") { - // TODO: Apply NS-wide default (https://github.com/TheThingsIndustries/lorawan-stack/issues/1544) - req.Device.MACSettings.ADRMargin = 15 - paths = append(paths, "mac_settings.adr_margin") - } else if req.Device.MACSettings.ADRMargin == 0 { + if ttnpb.HasAnyField(paths, "mac_settings.adr_margin") && req.Device.GetMACSettings().GetADRMargin() == nil { return nil, nil, errInvalidADRMargin } - - if !ttnpb.HasAnyField(paths, "mac_settings.class_b_timeout") { - // TODO: Apply NS-wide default if not set (https://github.com/TheThingsIndustries/lorawan-stack/issues/1544) - req.Device.MACSettings.ClassBTimeout = time.Minute - paths = append(paths, "mac_settings.class_b_timeout") - } else if req.Device.MACSettings.ClassBTimeout == 0 { + if ttnpb.HasAnyField(paths, "mac_settings.class_b_timeout") && req.Device.GetMACSettings().GetClassBTimeout() == nil { return nil, nil, errInvalidClassBTimeout } - - if !ttnpb.HasAnyField(paths, "mac_settings.class_c_timeout") { - // TODO: Apply NS-wide default if not set (https://github.com/TheThingsIndustries/lorawan-stack/issues/1544) - req.Device.MACSettings.ClassCTimeout = 10 * time.Second - paths = append(paths, "mac_settings.class_c_timeout") - } else if req.Device.MACSettings.ClassCTimeout == 0 { + if ttnpb.HasAnyField(paths, "mac_settings.class_c_timeout") && req.Device.GetMACSettings().GetClassCTimeout() == nil { return nil, nil, errInvalidClassCTimeout } + if !ttnpb.HasAnyField(paths, "uses_32_bit_f_cnt") { + dev.Uses32BitFCnt = true + paths = append(paths, "uses_32_bit_f_cnt") + } + if req.Device.SupportsJoin { return &req.Device, paths, nil } @@ -149,7 +130,7 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest req.Device.Session.StartedAt = time.Now().UTC() paths = append(paths, "session.started_at") - if err := resetMACState(&req.Device, ns.FrequencyPlans); err != nil { + if err := resetMACState(&req.Device, ns.FrequencyPlans, ns.defaultMACSettings); err != nil { return nil, nil, err } if req.Device.MACState.DeviceClass != ttnpb.CLASS_A { diff --git a/pkg/networkserver/grpc_deviceregistry_test.go b/pkg/networkserver/grpc_deviceregistry_test.go index f8ff2f2d87..de251955e6 100644 --- a/pkg/networkserver/grpc_deviceregistry_test.go +++ b/pkg/networkserver/grpc_deviceregistry_test.go @@ -215,7 +215,6 @@ func TestDeviceRegistrySet(t *testing.T) { Device: ttnpb.EndDevice{ EndDeviceIdentifiers: ids, SupportsJoin: true, - MACSettings: &ttnpb.MACSettings{}, }, FieldMask: pbtypes.FieldMask{ Paths: []string{ @@ -267,6 +266,7 @@ func TestDeviceRegistrySet(t *testing.T) { "frequency_plan_id", "lorawan_phy_version", "lorawan_version", + "mac_settings.adr_margin", "mac_settings.use_adr", "resets_f_cnt", "resets_join_nonces", @@ -283,8 +283,6 @@ func TestDeviceRegistrySet(t *testing.T) { "lorawan_phy_version", "lorawan_version", "mac_settings.adr_margin", - "mac_settings.class_b_timeout", - "mac_settings.class_c_timeout", "mac_settings.use_adr", "resets_f_cnt", "resets_join_nonces", @@ -297,18 +295,14 @@ func TestDeviceRegistrySet(t *testing.T) { EndDeviceIdentifiers: ids, SupportsJoin: true, MACSettings: &ttnpb.MACSettings{ - ADRMargin: 15, - ClassBTimeout: time.Minute, - ClassCTimeout: 10 * time.Second, + ADRMargin: &pbtypes.FloatValue{Value: 4}, }, }) return &ttnpb.EndDevice{ EndDeviceIdentifiers: ids, SupportsJoin: true, MACSettings: &ttnpb.MACSettings{ - ADRMargin: 15, - ClassBTimeout: time.Minute, - ClassCTimeout: 10 * time.Second, + ADRMargin: &pbtypes.FloatValue{Value: 4}, }, }, nil }, @@ -316,13 +310,16 @@ func TestDeviceRegistrySet(t *testing.T) { Device: ttnpb.EndDevice{ EndDeviceIdentifiers: ids, SupportsJoin: true, - MACSettings: &ttnpb.MACSettings{}, + MACSettings: &ttnpb.MACSettings{ + ADRMargin: &pbtypes.FloatValue{Value: 4}, + }, }, FieldMask: pbtypes.FieldMask{ Paths: []string{ "frequency_plan_id", "lorawan_phy_version", "lorawan_version", + "mac_settings.adr_margin", "mac_settings.use_adr", "resets_f_cnt", "resets_join_nonces", @@ -337,9 +334,7 @@ func TestDeviceRegistrySet(t *testing.T) { EndDeviceIdentifiers: ids, SupportsJoin: true, MACSettings: &ttnpb.MACSettings{ - ADRMargin: 15, - ClassBTimeout: time.Minute, - ClassCTimeout: 10 * time.Second, + ADRMargin: &pbtypes.FloatValue{Value: 4}, }, }, ContextAssertion: func(ctx context.Context) bool { diff --git a/pkg/networkserver/grpc_gsns.go b/pkg/networkserver/grpc_gsns.go index 6758e2b212..403df98b7f 100644 --- a/pkg/networkserver/grpc_gsns.go +++ b/pkg/networkserver/grpc_gsns.go @@ -552,7 +552,7 @@ func (ns *NetworkServer) handleUplink(ctx context.Context, up *ttnpb.UplinkMessa if stored.MACState != nil { stored.MACState.PendingApplicationDownlink = nil - } else if err := resetMACState(stored, ns.FrequencyPlans); err != nil { + } else if err := resetMACState(stored, ns.FrequencyPlans, ns.defaultMACSettings); err != nil { handleErr = true return nil, nil, err } @@ -566,7 +566,7 @@ func (ns *NetworkServer) handleUplink(ctx context.Context, up *ttnpb.UplinkMessa cmd, cmds = cmds[0], cmds[1:] switch cmd.CID { case ttnpb.CID_RESET: - err = handleResetInd(ctx, stored, cmd.GetResetInd(), ns.FrequencyPlans) + err = handleResetInd(ctx, stored, cmd.GetResetInd(), ns.FrequencyPlans, ns.defaultMACSettings) case ttnpb.CID_LINK_CHECK: err = handleLinkCheckReq(ctx, stored, up) case ttnpb.CID_LINK_ADR: @@ -659,7 +659,9 @@ func (ns *NetworkServer) handleUplink(ctx context.Context, up *ttnpb.UplinkMessa stored.MACState.PendingJoinRequest = nil paths = append(paths, "recent_adr_uplinks") - if !pld.FHDR.ADR { + if !pld.FHDR.ADR || + stored.MACSettings.GetUseADR() != nil && !stored.MACSettings.UseADR.Value || + ns.defaultMACSettings.GetUseADR() != nil && !ns.defaultMACSettings.UseADR.Value { stored.RecentADRUplinks = nil return stored, paths, nil } @@ -669,7 +671,7 @@ func (ns *NetworkServer) handleUplink(ctx context.Context, up *ttnpb.UplinkMessa stored.RecentADRUplinks = append(stored.RecentADRUplinks[:0], stored.RecentADRUplinks[len(stored.RecentADRUplinks)-recentUplinkCount:]...) } - if err := adaptDataRate(stored, ns.FrequencyPlans); err != nil { + if err := adaptDataRate(stored, ns.FrequencyPlans, ns.defaultMACSettings); err != nil { handleErr = true return nil, nil, err } @@ -713,10 +715,11 @@ func (ns *NetworkServer) handleUplink(ctx context.Context, up *ttnpb.UplinkMessa // newDevAddr generates a DevAddr for specified EndDevice. func (ns *NetworkServer) newDevAddr(context.Context, *ttnpb.EndDevice) types.DevAddr { - nwkAddr := make([]byte, types.NwkAddrLength(ns.NetID)) + // TODO: Allow generating DevAddr from a prefix. (https://github.com/TheThingsNetwork/lorawan-stack/issues/130) + nwkAddr := make([]byte, types.NwkAddrLength(ns.netID)) random.Read(nwkAddr) - nwkAddr[0] &= 0xff >> (8 - types.NwkAddrBits(ns.NetID)%8) - devAddr, err := types.NewDevAddr(ns.NetID, nwkAddr) + nwkAddr[0] &= 0xff >> (8 - types.NwkAddrBits(ns.netID)%8) + devAddr, err := types.NewDevAddr(ns.netID, nwkAddr) if err != nil { panic(errors.New("failed to create new DevAddr").WithCause(err)) } @@ -764,7 +767,7 @@ func (ns *NetworkServer) handleJoin(ctx context.Context, up *ttnpb.UplinkMessage logger = logger.WithField("dev_addr", devAddr) ctx = log.NewContext(ctx, logger) - if err := resetMACState(dev, ns.FrequencyPlans); err != nil { + if err := resetMACState(dev, ns.FrequencyPlans, ns.defaultMACSettings); err != nil { logger.WithError(err).Error("Failed to reset device's MAC state") return err } @@ -778,7 +781,7 @@ func (ns *NetworkServer) handleJoin(ctx context.Context, up *ttnpb.UplinkMessage CFList: frequencyplans.CFList(*fp, dev.LoRaWANPHYVersion), CorrelationIDs: events.CorrelationIDsFromContext(ctx), DevAddr: devAddr, - NetID: ns.NetID, + NetID: ns.netID, Payload: up.Payload, RawPayload: up.RawPayload, RxDelay: dev.MACState.DesiredParameters.Rx1Delay, @@ -834,7 +837,7 @@ func (ns *NetworkServer) handleJoin(ctx context.Context, up *ttnpb.UplinkMessage func(dev *ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error) { var paths []string - if err := resetMACState(dev, ns.Component.FrequencyPlans); err != nil { + if err := resetMACState(dev, ns.Component.FrequencyPlans, ns.defaultMACSettings); err != nil { resetErr = true return nil, nil, err } diff --git a/pkg/networkserver/grpc_gsns_test.go b/pkg/networkserver/grpc_gsns_test.go index 538821f129..269bae8c52 100644 --- a/pkg/networkserver/grpc_gsns_test.go +++ b/pkg/networkserver/grpc_gsns_test.go @@ -61,10 +61,6 @@ var ( } ) -func init() { - SetAppQueueUpdateTimeout(0) -} - type UplinkHandler interface { HandleUplink(context.Context, *ttnpb.UplinkMessage) (*pbtypes.Empty, error) } @@ -1195,7 +1191,7 @@ func handleUplinkTest() func(t *testing.T) { pb.CreatedAt = ret.CreatedAt pb.UpdatedAt = ret.UpdatedAt if pb.MACState == nil { - err := ResetMACState(pb, ns.FrequencyPlans) + err := ResetMACState(pb, ns.FrequencyPlans, ttnpb.MACSettings{}) if !a.So(err, should.BeNil) { t.FailNow() } @@ -1621,6 +1617,7 @@ func handleJoinTest() func(t *testing.T) { ns := test.Must(New( component.MustNew(test.GetLogger(t), &component.Config{}), &Config{ + NetID: NetID, Devices: devReg, DownlinkTasks: &MockDownlinkTaskQueue{ AddFunc: func(ctx context.Context, devID ttnpb.EndDeviceIdentifiers, t time.Time) error { @@ -1677,7 +1674,7 @@ func handleJoinTest() func(t *testing.T) { pb.UpdatedAt = ret.UpdatedAt a.So(ret, should.Resemble, pb) - err = ResetMACState(ret, ns.FrequencyPlans) + err = ResetMACState(ret, ns.FrequencyPlans, ttnpb.MACSettings{}) if !a.So(err, should.BeNil) { t.Fatalf("Failed to reset MAC state: %s", err) } @@ -1686,7 +1683,7 @@ func handleJoinTest() func(t *testing.T) { expectedRequest := &ttnpb.JoinRequest{ RawPayload: append(tc.UplinkMessage.RawPayload[:0:0], tc.UplinkMessage.RawPayload...), Payload: CopyUplinkMessage(tc.UplinkMessage).Payload, - NetID: ns.NetID, + NetID: NetID, SelectedMACVersion: pb.LoRaWANVersion, RxDelay: pb.MACState.DesiredParameters.Rx1Delay, CFList: frequencyplans.CFList(*test.Must(ns.FrequencyPlans.GetByID(test.EUFrequencyPlanID)).(*frequencyplans.FrequencyPlan), pb.LoRaWANPHYVersion), diff --git a/pkg/networkserver/mac_dev_status.go b/pkg/networkserver/mac_dev_status.go index ce1f50d876..3544d440dc 100644 --- a/pkg/networkserver/mac_dev_status.go +++ b/pkg/networkserver/mac_dev_status.go @@ -27,10 +27,30 @@ var ( evtReceiveDevStatusAnswer = defineReceiveMACAnswerEvent("dev_status", "device status")() ) -func enqueueDevStatusReq(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, maxUpLen uint16) (uint16, uint16, bool) { - if dev.LastDevStatusReceivedAt != nil && - (dev.MACSettings.StatusCountPeriodicity == 0 || dev.MACState.LastDevStatusFCntUp+dev.MACSettings.StatusCountPeriodicity > dev.Session.LastFCntUp) && - (dev.MACSettings.StatusTimePeriodicity == 0 || dev.LastDevStatusReceivedAt.Add(dev.MACSettings.StatusTimePeriodicity).After(time.Now())) { +const ( + DefaultStatusCountPeriodicity uint32 = 20 + DefaultStatusTimePeriodicity = time.Hour +) + +func enqueueDevStatusReq(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, maxUpLen uint16, defaults ttnpb.MACSettings) (uint16, uint16, bool) { + cp := DefaultStatusCountPeriodicity + if dev.GetMACSettings().GetStatusCountPeriodicity() != nil { + cp = dev.MACSettings.StatusCountPeriodicity.Value + } else if defaults.StatusCountPeriodicity != nil { + cp = defaults.StatusCountPeriodicity.Value + } + + tp := DefaultStatusTimePeriodicity + if dev.GetMACSettings().GetStatusTimePeriodicity() != nil { + tp = *dev.MACSettings.StatusTimePeriodicity + } else if defaults.StatusCountPeriodicity != nil { + tp = *defaults.StatusTimePeriodicity + } + + if cp == 0 && tp == 0 || + dev.LastDevStatusReceivedAt != nil && + (cp == 0 || dev.MACState.LastDevStatusFCntUp+cp > dev.Session.LastFCntUp) && + (tp == 0 || dev.LastDevStatusReceivedAt.Add(tp).After(time.Now())) { return maxDownLen, maxUpLen, true } diff --git a/pkg/networkserver/mac_reset.go b/pkg/networkserver/mac_reset.go index d62e7d5949..cb4d98bb63 100644 --- a/pkg/networkserver/mac_reset.go +++ b/pkg/networkserver/mac_reset.go @@ -27,7 +27,7 @@ var ( evtEnqueueResetConfirmation = defineEnqueueMACConfirmationEvent("reset", "device reset")() ) -func handleResetInd(ctx context.Context, dev *ttnpb.EndDevice, pld *ttnpb.MACCommand_ResetInd, fps *frequencyplans.Store) error { +func handleResetInd(ctx context.Context, dev *ttnpb.EndDevice, pld *ttnpb.MACCommand_ResetInd, fps *frequencyplans.Store, defaults ttnpb.MACSettings) error { if pld == nil { return errNoPayload } @@ -38,7 +38,7 @@ func handleResetInd(ctx context.Context, dev *ttnpb.EndDevice, pld *ttnpb.MACCom return nil } - if err := resetMACState(dev, fps); err != nil { + if err := resetMACState(dev, fps, defaults); err != nil { return err } dev.MACState.LoRaWANVersion = ttnpb.MAC_V1_1 diff --git a/pkg/networkserver/mac_reset_test.go b/pkg/networkserver/mac_reset_test.go index fe1eff51d9..583108e665 100644 --- a/pkg/networkserver/mac_reset_test.go +++ b/pkg/networkserver/mac_reset_test.go @@ -41,13 +41,11 @@ func TestHandleResetInd(t *testing.T) { LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, SupportsJoin: false, MACState: &ttnpb.MACState{}, - MACSettings: &ttnpb.MACSettings{}, }, Expected: &ttnpb.EndDevice{ LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, SupportsJoin: false, MACState: &ttnpb.MACState{}, - MACSettings: &ttnpb.MACSettings{}, }, AssertEvents: func(t *testing.T, evs ...events.Event) bool { return assertions.New(t).So(evs, should.BeEmpty) @@ -68,7 +66,6 @@ func TestHandleResetInd(t *testing.T) { DesiredParameters: *ttnpb.NewPopulatedMACParameters(test.Randy, false), QueuedResponses: []*ttnpb.MACCommand{}, }, - MACSettings: &ttnpb.MACSettings{}, }, Expected: func() *ttnpb.EndDevice { dev := &ttnpb.EndDevice{ @@ -78,9 +75,8 @@ func TestHandleResetInd(t *testing.T) { LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, SupportsJoin: false, FrequencyPlanID: test.EUFrequencyPlanID, - MACSettings: &ttnpb.MACSettings{}, } - if err := ResetMACState(dev, frequencyplans.NewStore(test.FrequencyPlansFetcher)); err != nil { + if err := ResetMACState(dev, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{}); err != nil { t.Fatalf("Failed to reset MACState: %v", errors.Stack(err)) } @@ -126,7 +122,6 @@ func TestHandleResetInd(t *testing.T) { {}, }, }, - MACSettings: &ttnpb.MACSettings{}, }, Expected: func() *ttnpb.EndDevice { dev := &ttnpb.EndDevice{ @@ -136,9 +131,8 @@ func TestHandleResetInd(t *testing.T) { LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, SupportsJoin: false, FrequencyPlanID: test.EUFrequencyPlanID, - MACSettings: &ttnpb.MACSettings{}, } - if err := ResetMACState(dev, frequencyplans.NewStore(test.FrequencyPlansFetcher)); err != nil { + if err := ResetMACState(dev, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{}); err != nil { t.Fatalf("Failed to reset MACState: %v", errors.Stack(err)) } @@ -174,7 +168,7 @@ func TestHandleResetInd(t *testing.T) { var err error evs := collectEvents(func() { - err = handleResetInd(test.Context(), dev, tc.Payload, frequencyplans.NewStore(test.FrequencyPlansFetcher)) + err = handleResetInd(test.Context(), dev, tc.Payload, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{}) }) if tc.Error != nil && !a.So(err, should.EqualErrorOrDefinition, tc.Error) || tc.Error == nil && !a.So(err, should.BeNil) { diff --git a/pkg/networkserver/networkserver.go b/pkg/networkserver/networkserver.go index 96e08ffd7a..5eae3a68be 100644 --- a/pkg/networkserver/networkserver.go +++ b/pkg/networkserver/networkserver.go @@ -111,7 +111,7 @@ type NetworkServer struct { devices DeviceRegistry - NetID types.NetID + netID types.NetID applicationServersMu *sync.RWMutex applicationServers map[string]*applicationUpStream @@ -131,6 +131,8 @@ type NetworkServer struct { jsClient NsJsClientFunc handleASUplink func(ctx context.Context, ids ttnpb.ApplicationIdentifiers, up *ttnpb.ApplicationUp) (bool, error) + + defaultMACSettings ttnpb.MACSettings } // Option configures the NetworkServer. @@ -197,14 +199,16 @@ func New(c *component.Component, conf *Config, opts ...Option) (*NetworkServer, ns := &NetworkServer{ Component: c, devices: conf.Devices, - downlinkTasks: conf.DownlinkTasks, - downlinkPriorities: downlinkPriorities, + netID: conf.NetID, applicationServersMu: &sync.RWMutex{}, applicationServers: make(map[string]*applicationUpStream), metadataAccumulators: &sync.Map{}, metadataAccumulatorPool: &sync.Pool{}, hashPool: &sync.Pool{}, macHandlers: &sync.Map{}, + downlinkTasks: conf.DownlinkTasks, + downlinkPriorities: downlinkPriorities, + defaultMACSettings: conf.DefaultMACSettings, } ns.hashPool.New = func() interface{} { return fnv.New64a() diff --git a/pkg/networkserver/networkserver_util_test.go b/pkg/networkserver/networkserver_util_test.go index f1aa87075d..9698c367ad 100644 --- a/pkg/networkserver/networkserver_util_test.go +++ b/pkg/networkserver/networkserver_util_test.go @@ -42,6 +42,7 @@ var ( NwkSEncKey = types.AES128Key{0x42, 0x42, 0x42, 0x42, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} AppSKey = types.AES128Key{0x42, 0x42, 0x42, 0x42, 0x42, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} + NetID = types.NetID{0x42, 0x41, 0x43} DevAddr = types.DevAddr{0x42, 0x42, 0xff, 0xff} DevEUI = types.EUI64{0x42, 0x42, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} JoinEUI = types.EUI64{0x42, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} @@ -61,8 +62,8 @@ func CopyUplinkMessage(pb *ttnpb.UplinkMessage) *ttnpb.UplinkMessage { return deepcopy.Copy(pb).(*ttnpb.UplinkMessage) } -func SetAppQueueUpdateTimeout(d time.Duration) { - appQueueUpdateTimeout = d +func DurationPtr(v time.Duration) *time.Duration { + return &v } var _ DownlinkTaskQueue = MockDownlinkTaskQueue{} diff --git a/pkg/networkserver/utils.go b/pkg/networkserver/utils.go index 8b2be26101..ad47d9fe01 100644 --- a/pkg/networkserver/utils.go +++ b/pkg/networkserver/utils.go @@ -61,7 +61,7 @@ func searchUplinkChannel(freq uint64, dev *ttnpb.EndDevice) (uint8, error) { return 0, errUplinkChannelNotFound.WithAttributes("frequency", freq) } -func resetMACState(dev *ttnpb.EndDevice, fps *frequencyplans.Store) error { +func resetMACState(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults ttnpb.MACSettings) error { fp, band, err := getDeviceBandVersion(dev, fps) if err != nil { return err @@ -160,14 +160,26 @@ outerDown: dev.MACState.DesiredParameters.UplinkDwellTime = fp.DwellTime.GetUplinks() dev.MACState.DesiredParameters.DownlinkDwellTime = fp.DwellTime.GetDownlinks() - // TODO: Apply NS-wide default (https://github.com/TheThingsIndustries/lorawan-stack/issues/1544) - dev.MACState.DesiredParameters.Rx1Delay = ttnpb.RX_DELAY_5 + if dev.GetMACSettings().GetRx1Delay() != nil { + dev.MACState.DesiredParameters.Rx1Delay = dev.MACSettings.Rx1Delay.Value + } else if defaults.Rx1Delay != nil { + dev.MACState.DesiredParameters.Rx1Delay = defaults.Rx1Delay.Value + } - if fp.Rx2Channel != nil { + if dev.GetMACSettings().GetRx2Frequency() != nil { + dev.MACState.DesiredParameters.Rx2Frequency = dev.MACSettings.Rx2Frequency.Value + } else if fp.Rx2Channel != nil { dev.MACState.DesiredParameters.Rx2Frequency = fp.Rx2Channel.Frequency + } else if defaults.Rx2Frequency != nil { + dev.MACState.DesiredParameters.Rx2Frequency = defaults.Rx2Frequency.Value } - if fp.DefaultRx2DataRate != nil { + + if dev.GetMACSettings().GetRx2DataRateIndex() != nil { + dev.MACState.DesiredParameters.Rx2DataRateIndex = dev.MACSettings.Rx2DataRateIndex.Value + } else if fp.DefaultRx2DataRate != nil { dev.MACState.DesiredParameters.Rx2DataRateIndex = ttnpb.DataRateIndex(*fp.DefaultRx2DataRate) + } else if defaults.Rx2DataRateIndex != nil { + dev.MACState.DesiredParameters.Rx2DataRateIndex = defaults.Rx2DataRateIndex.Value } if fp.PingSlot != nil { @@ -176,23 +188,10 @@ outerDown: if fp.DefaultPingSlotDataRate != nil { dev.MACState.DesiredParameters.PingSlotDataRateIndex = ttnpb.DataRateIndex(*fp.DefaultPingSlotDataRate) } - if fp.MaxEIRP != nil && *fp.MaxEIRP > 0 { dev.MACState.DesiredParameters.MaxEIRP = float32(math.Min(float64(dev.MACState.CurrentParameters.MaxEIRP), float64(*fp.MaxEIRP))) } - if dev.MACSettings.Rx1Delay != nil { - dev.MACState.DesiredParameters.Rx1Delay = dev.MACSettings.Rx1Delay.Value - } - - if dev.MACSettings.Rx2Frequency != nil { - dev.MACState.DesiredParameters.Rx2Frequency = dev.MACSettings.Rx2Frequency.Value - } - - if dev.MACSettings.Rx2DataRateIndex != nil { - dev.MACState.DesiredParameters.Rx2DataRateIndex = dev.MACSettings.Rx2DataRateIndex.Value - } - if dev.DefaultMACParameters != nil { dev.MACState.CurrentParameters = deepcopy.Copy(*dev.DefaultMACParameters).(ttnpb.MACParameters) } diff --git a/pkg/networkserver/utils_internal_test.go b/pkg/networkserver/utils_internal_test.go index c9537f7dd5..e999d8b0a2 100644 --- a/pkg/networkserver/utils_internal_test.go +++ b/pkg/networkserver/utils_internal_test.go @@ -296,7 +296,7 @@ func TestResetMACState(t *testing.T) { pb := CopyEndDevice(tc.Device) - err := resetMACState(pb, tc.FrequencyPlanStore) + err := resetMACState(pb, tc.FrequencyPlanStore, ttnpb.MACSettings{}) if tc.ErrorAssertion != nil { a.So(tc.ErrorAssertion(t, err), should.BeTrue) } else { From 9259a7bf32099955397f27da9b7df0052e7e5fef Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 8 Feb 2019 19:24:12 +0100 Subject: [PATCH 07/40] api: Make MACSettings.adr_margin a float --- api/api.md | 2 +- api/api.swagger.json | 4 +- api/end_device.proto | 2 +- pkg/ttnpb/end_device.pb.go | 506 ++++++++++++++++++------------------- 4 files changed, 257 insertions(+), 257 deletions(-) diff --git a/api/api.md b/api/api.md index 4d690e2a04..bcd7a51fb1 100644 --- a/api/api.md +++ b/api/api.md @@ -1785,7 +1785,7 @@ This is used internally by the Network Server and is read only. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | use_adr | [google.protobuf.BoolValue](#google.protobuf.BoolValue) | | | -| adr_margin | [google.protobuf.UInt32Value](#google.protobuf.UInt32Value) | | The ADR margin tells the network server how much margin it should add in ADR requests. A bigger margin is less efficient, but gives a better chance of successful reception. | +| adr_margin | [google.protobuf.FloatValue](#google.protobuf.FloatValue) | | The ADR margin tells the network server how much margin it should add in ADR requests. A bigger margin is less efficient, but gives a better chance of successful reception. | | class_b_timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | Deadline for the device to respond to requests from the Network Server. | | class_c_timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | Deadline for the device to respond to requests from the Network Server. | | status_time_periodicity | [google.protobuf.Duration](#google.protobuf.Duration) | | The interval after which a DevStatusReq MACCommand shall be sent. | diff --git a/api/api.swagger.json b/api/api.swagger.json index 047cf7de3c..689f523a18 100644 --- a/api/api.swagger.json +++ b/api/api.swagger.json @@ -7434,8 +7434,8 @@ "format": "boolean" }, "adr_margin": { - "type": "integer", - "format": "int64", + "type": "number", + "format": "float", "description": "The ADR margin tells the network server how much margin it should add in ADR requests.\nA bigger margin is less efficient, but gives a better chance of successful reception." }, "class_b_timeout": { diff --git a/api/end_device.proto b/api/end_device.proto index b57b5cca16..4223028488 100644 --- a/api/end_device.proto +++ b/api/end_device.proto @@ -179,7 +179,7 @@ message MACSettings { google.protobuf.BoolValue use_adr = 1 [(gogoproto.customname) = "UseADR"]; // The ADR margin tells the network server how much margin it should add in ADR requests. // A bigger margin is less efficient, but gives a better chance of successful reception. - google.protobuf.UInt32Value adr_margin = 2 [(gogoproto.customname) = "ADRMargin"]; + google.protobuf.FloatValue adr_margin = 2 [(gogoproto.customname) = "ADRMargin"]; // Deadline for the device to respond to requests from the Network Server. google.protobuf.Duration class_b_timeout = 3 [(gogoproto.stdduration) = true]; // Deadline for the device to respond to requests from the Network Server. diff --git a/pkg/ttnpb/end_device.pb.go b/pkg/ttnpb/end_device.pb.go index b681a5c86e..75ced02f13 100644 --- a/pkg/ttnpb/end_device.pb.go +++ b/pkg/ttnpb/end_device.pb.go @@ -62,7 +62,7 @@ var PowerState_value = map[string]int32{ } func (PowerState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{0} + return fileDescriptor_end_device_f29faf389d9d861a, []int{0} } type Session struct { @@ -87,7 +87,7 @@ type Session struct { func (m *Session) Reset() { *m = Session{} } func (*Session) ProtoMessage() {} func (*Session) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{0} + return fileDescriptor_end_device_f29faf389d9d861a, []int{0} } func (m *Session) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -199,7 +199,7 @@ type MACParameters struct { func (m *MACParameters) Reset() { *m = MACParameters{} } func (*MACParameters) ProtoMessage() {} func (*MACParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{1} + return fileDescriptor_end_device_f29faf389d9d861a, []int{1} } func (m *MACParameters) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -379,7 +379,7 @@ type MACParameters_Channel struct { func (m *MACParameters_Channel) Reset() { *m = MACParameters_Channel{} } func (*MACParameters_Channel) ProtoMessage() {} func (*MACParameters_Channel) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{1, 0} + return fileDescriptor_end_device_f29faf389d9d861a, []int{1, 0} } func (m *MACParameters_Channel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -456,7 +456,7 @@ type EndDeviceBrand struct { func (m *EndDeviceBrand) Reset() { *m = EndDeviceBrand{} } func (*EndDeviceBrand) ProtoMessage() {} func (*EndDeviceBrand) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{2} + return fileDescriptor_end_device_f29faf389d9d861a, []int{2} } func (m *EndDeviceBrand) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -524,7 +524,7 @@ type EndDeviceModel struct { func (m *EndDeviceModel) Reset() { *m = EndDeviceModel{} } func (*EndDeviceModel) ProtoMessage() {} func (*EndDeviceModel) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{3} + return fileDescriptor_end_device_f29faf389d9d861a, []int{3} } func (m *EndDeviceModel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -587,7 +587,7 @@ type EndDeviceVersionIdentifiers struct { func (m *EndDeviceVersionIdentifiers) Reset() { *m = EndDeviceVersionIdentifiers{} } func (*EndDeviceVersionIdentifiers) ProtoMessage() {} func (*EndDeviceVersionIdentifiers) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{4} + return fileDescriptor_end_device_f29faf389d9d861a, []int{4} } func (m *EndDeviceVersionIdentifiers) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -683,7 +683,7 @@ type EndDeviceVersion struct { func (m *EndDeviceVersion) Reset() { *m = EndDeviceVersion{} } func (*EndDeviceVersion) ProtoMessage() {} func (*EndDeviceVersion) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{5} + return fileDescriptor_end_device_f29faf389d9d861a, []int{5} } func (m *EndDeviceVersion) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -814,7 +814,7 @@ type MACSettings struct { UseADR *types.BoolValue `protobuf:"bytes,1,opt,name=use_adr,json=useAdr,proto3" json:"use_adr,omitempty"` // The ADR margin tells the network server how much margin it should add in ADR requests. // A bigger margin is less efficient, but gives a better chance of successful reception. - ADRMargin *types.UInt32Value `protobuf:"bytes,2,opt,name=adr_margin,json=adrMargin,proto3" json:"adr_margin,omitempty"` + ADRMargin *types.FloatValue `protobuf:"bytes,2,opt,name=adr_margin,json=adrMargin,proto3" json:"adr_margin,omitempty"` // Deadline for the device to respond to requests from the Network Server. ClassBTimeout *time.Duration `protobuf:"bytes,3,opt,name=class_b_timeout,json=classBTimeout,proto3,stdduration" json:"class_b_timeout,omitempty"` // Deadline for the device to respond to requests from the Network Server. @@ -833,7 +833,7 @@ type MACSettings struct { func (m *MACSettings) Reset() { *m = MACSettings{} } func (*MACSettings) ProtoMessage() {} func (*MACSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{6} + return fileDescriptor_end_device_f29faf389d9d861a, []int{6} } func (m *MACSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -869,7 +869,7 @@ func (m *MACSettings) GetUseADR() *types.BoolValue { return nil } -func (m *MACSettings) GetADRMargin() *types.UInt32Value { +func (m *MACSettings) GetADRMargin() *types.FloatValue { if m != nil { return m.ADRMargin } @@ -934,7 +934,7 @@ type MACSettings_RxDelayValue struct { func (m *MACSettings_RxDelayValue) Reset() { *m = MACSettings_RxDelayValue{} } func (*MACSettings_RxDelayValue) ProtoMessage() {} func (*MACSettings_RxDelayValue) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{6, 0} + return fileDescriptor_end_device_f29faf389d9d861a, []int{6, 0} } func (m *MACSettings_RxDelayValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -979,7 +979,7 @@ type MACSettings_DataRateIndexValue struct { func (m *MACSettings_DataRateIndexValue) Reset() { *m = MACSettings_DataRateIndexValue{} } func (*MACSettings_DataRateIndexValue) ProtoMessage() {} func (*MACSettings_DataRateIndexValue) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{6, 1} + return fileDescriptor_end_device_f29faf389d9d861a, []int{6, 1} } func (m *MACSettings_DataRateIndexValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1061,7 +1061,7 @@ type MACState struct { func (m *MACState) Reset() { *m = MACState{} } func (*MACState) ProtoMessage() {} func (*MACState) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{7} + return fileDescriptor_end_device_f29faf389d9d861a, []int{7} } func (m *MACState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1195,7 +1195,7 @@ type MACState_JoinAccept struct { func (m *MACState_JoinAccept) Reset() { *m = MACState_JoinAccept{} } func (*MACState_JoinAccept) ProtoMessage() {} func (*MACState_JoinAccept) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{7, 0} + return fileDescriptor_end_device_f29faf389d9d861a, []int{7, 0} } func (m *MACState_JoinAccept) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1392,7 +1392,7 @@ type EndDevice struct { func (m *EndDevice) Reset() { *m = EndDevice{} } func (*EndDevice) ProtoMessage() {} func (*EndDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{8} + return fileDescriptor_end_device_f29faf389d9d861a, []int{8} } func (m *EndDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1738,7 +1738,7 @@ type EndDevices struct { func (m *EndDevices) Reset() { *m = EndDevices{} } func (*EndDevices) ProtoMessage() {} func (*EndDevices) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{9} + return fileDescriptor_end_device_f29faf389d9d861a, []int{9} } func (m *EndDevices) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1783,7 +1783,7 @@ type CreateEndDeviceRequest struct { func (m *CreateEndDeviceRequest) Reset() { *m = CreateEndDeviceRequest{} } func (*CreateEndDeviceRequest) ProtoMessage() {} func (*CreateEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{10} + return fileDescriptor_end_device_f29faf389d9d861a, []int{10} } func (m *CreateEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1822,7 +1822,7 @@ type UpdateEndDeviceRequest struct { func (m *UpdateEndDeviceRequest) Reset() { *m = UpdateEndDeviceRequest{} } func (*UpdateEndDeviceRequest) ProtoMessage() {} func (*UpdateEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{11} + return fileDescriptor_end_device_f29faf389d9d861a, []int{11} } func (m *UpdateEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1868,7 +1868,7 @@ type GetEndDeviceRequest struct { func (m *GetEndDeviceRequest) Reset() { *m = GetEndDeviceRequest{} } func (*GetEndDeviceRequest) ProtoMessage() {} func (*GetEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{12} + return fileDescriptor_end_device_f29faf389d9d861a, []int{12} } func (m *GetEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1921,7 +1921,7 @@ type ListEndDevicesRequest struct { func (m *ListEndDevicesRequest) Reset() { *m = ListEndDevicesRequest{} } func (*ListEndDevicesRequest) ProtoMessage() {} func (*ListEndDevicesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{13} + return fileDescriptor_end_device_f29faf389d9d861a, []int{13} } func (m *ListEndDevicesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1988,7 +1988,7 @@ type SetEndDeviceRequest struct { func (m *SetEndDeviceRequest) Reset() { *m = SetEndDeviceRequest{} } func (*SetEndDeviceRequest) ProtoMessage() {} func (*SetEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_1fd831da224133be, []int{14} + return fileDescriptor_end_device_f29faf389d9d861a, []int{14} } func (m *SetEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4616,7 +4616,7 @@ func NewPopulatedMACSettings(r randyEndDevice, easy bool) *MACSettings { this.UseADR = types.NewPopulatedBoolValue(r, easy) } if r.Intn(10) != 0 { - this.ADRMargin = types.NewPopulatedUInt32Value(r, easy) + this.ADRMargin = types.NewPopulatedFloatValue(r, easy) } if r.Intn(10) != 0 { this.ClassBTimeout = github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy) @@ -5631,7 +5631,7 @@ func (this *MACSettings) String() string { } s := strings.Join([]string{`&MACSettings{`, `UseADR:` + strings.Replace(fmt.Sprintf("%v", this.UseADR), "BoolValue", "types.BoolValue", 1) + `,`, - `ADRMargin:` + strings.Replace(fmt.Sprintf("%v", this.ADRMargin), "UInt32Value", "types.UInt32Value", 1) + `,`, + `ADRMargin:` + strings.Replace(fmt.Sprintf("%v", this.ADRMargin), "FloatValue", "types.FloatValue", 1) + `,`, `ClassBTimeout:` + strings.Replace(fmt.Sprintf("%v", this.ClassBTimeout), "Duration", "types.Duration", 1) + `,`, `ClassCTimeout:` + strings.Replace(fmt.Sprintf("%v", this.ClassCTimeout), "Duration", "types.Duration", 1) + `,`, `StatusTimePeriodicity:` + strings.Replace(fmt.Sprintf("%v", this.StatusTimePeriodicity), "Duration", "types.Duration", 1) + `,`, @@ -7581,7 +7581,7 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.ADRMargin == nil { - m.ADRMargin = &types.UInt32Value{} + m.ADRMargin = &types.FloatValue{} } if err := m.ADRMargin.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -10785,234 +10785,234 @@ var ( ) func init() { - proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_1fd831da224133be) + proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_f29faf389d9d861a) } func init() { - golang_proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_1fd831da224133be) -} - -var fileDescriptor_end_device_1fd831da224133be = []byte{ - // 3542 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5a, 0x4b, 0x6c, 0x5b, 0xd7, - 0x99, 0x26, 0x25, 0x59, 0x22, 0x7f, 0x4a, 0x24, 0x75, 0x24, 0xdb, 0x37, 0x8a, 0x43, 0x2a, 0xb2, - 0x93, 0x2a, 0x69, 0x44, 0xdb, 0xb2, 0xd3, 0x87, 0xdb, 0xc2, 0x21, 0x45, 0x39, 0x91, 0x2b, 0xcb, - 0x9a, 0xe3, 0xd7, 0xa4, 0xad, 0x73, 0x71, 0xc4, 0x7b, 0x24, 0xdf, 0x88, 0xbc, 0xf7, 0xf6, 0x9c, - 0x43, 0x89, 0x9a, 0x07, 0xd0, 0xcd, 0x00, 0xdd, 0xb5, 0x8b, 0x19, 0xa0, 0x9b, 0x01, 0x8a, 0xc1, - 0x0c, 0x50, 0x0c, 0x66, 0xd1, 0x65, 0x96, 0x5d, 0x66, 0x99, 0x65, 0xd1, 0x05, 0x53, 0x53, 0x9b, - 0x2e, 0x0b, 0xcc, 0x26, 0xcb, 0xc1, 0x79, 0xdc, 0x07, 0x1f, 0x52, 0xa4, 0x64, 0xd2, 0x8d, 0x70, - 0xef, 0xff, 0x7f, 0xff, 0x77, 0xff, 0xf3, 0xfa, 0x1f, 0x87, 0x82, 0xa5, 0xa6, 0xcf, 0xc8, 0x21, - 0xf1, 0x56, 0xb8, 0x20, 0x8d, 0xfd, 0xeb, 0x24, 0x70, 0xaf, 0x53, 0xcf, 0xb1, 0x1d, 0x7a, 0xe0, - 0x36, 0x68, 0x25, 0x60, 0xbe, 0xf0, 0x51, 0x5e, 0x08, 0xaf, 0x62, 0x70, 0x95, 0x83, 0x5b, 0x0b, - 0x2b, 0x7b, 0xae, 0x78, 0xd1, 0xde, 0xa9, 0x34, 0xfc, 0xd6, 0xf5, 0x3d, 0x7f, 0xcf, 0xbf, 0xae, - 0x60, 0x3b, 0xed, 0x5d, 0xf5, 0xa6, 0x5e, 0xd4, 0x93, 0x36, 0x5f, 0xf8, 0x4e, 0x02, 0xde, 0x3a, - 0x74, 0xc5, 0xbe, 0x7f, 0x78, 0x7d, 0xcf, 0x5f, 0x51, 0xca, 0x95, 0x03, 0xd2, 0x74, 0x1d, 0x22, - 0x7c, 0xc6, 0xaf, 0x47, 0x8f, 0xc6, 0xee, 0xca, 0x9e, 0xef, 0xef, 0x35, 0xa9, 0xf2, 0x89, 0x78, - 0x9e, 0x2f, 0x88, 0x70, 0x7d, 0x8f, 0x1b, 0x6d, 0xc9, 0x68, 0xa3, 0x6f, 0x3b, 0x6d, 0xa6, 0x00, - 0x46, 0xbf, 0x38, 0xa8, 0xdf, 0x75, 0x69, 0xd3, 0xb1, 0x5b, 0x84, 0xef, 0x0f, 0xf0, 0x47, 0x08, - 0x2e, 0x58, 0xbb, 0x21, 0x8c, 0xb6, 0x3c, 0xa8, 0x15, 0x6e, 0x8b, 0x72, 0x41, 0x5a, 0xc1, 0x49, - 0x0e, 0x1c, 0x32, 0x12, 0x04, 0x94, 0x85, 0x0e, 0x5e, 0x1d, 0x9e, 0x59, 0xd7, 0xa1, 0x9e, 0x70, - 0x77, 0xdd, 0x18, 0x74, 0x65, 0x18, 0xf4, 0xb1, 0xef, 0x7a, 0x27, 0x6b, 0xf7, 0xe9, 0x51, 0x68, - 0x5b, 0x1e, 0xd6, 0x86, 0x8b, 0x64, 0xa6, 0x60, 0x18, 0xd0, 0xa2, 0x9c, 0x93, 0x3d, 0xca, 0x4f, - 0x43, 0x08, 0xe2, 0x10, 0x41, 0x34, 0x62, 0xe9, 0x57, 0xe3, 0x30, 0xf5, 0x88, 0x72, 0xee, 0xfa, - 0x1e, 0x7a, 0x06, 0x19, 0x87, 0x1e, 0xd8, 0xc4, 0x71, 0x98, 0x35, 0xb6, 0x98, 0x5e, 0x9e, 0xae, - 0xfd, 0xf0, 0xd3, 0x6e, 0x39, 0xf5, 0xa7, 0x6e, 0xf9, 0xf6, 0x9e, 0x5f, 0x11, 0x2f, 0xa8, 0x78, - 0xe1, 0x7a, 0x7b, 0xbc, 0xe2, 0x51, 0x71, 0xe8, 0xb3, 0xfd, 0xeb, 0xfd, 0xe4, 0xc1, 0xfe, 0xde, - 0x75, 0x71, 0x14, 0x50, 0x5e, 0xa9, 0xd3, 0x83, 0xaa, 0xe3, 0x30, 0x3c, 0xe5, 0xe8, 0x07, 0xf4, - 0x7d, 0x98, 0x90, 0xe3, 0xb2, 0xc6, 0x17, 0xd3, 0xcb, 0xb9, 0xd5, 0x57, 0x2b, 0xfd, 0xfb, 0xad, - 0x62, 0xbe, 0xff, 0x63, 0x7a, 0xc4, 0x6b, 0x19, 0xf9, 0xc5, 0xcf, 0xba, 0xe5, 0x34, 0x56, 0x26, - 0xe8, 0x75, 0x98, 0x69, 0x12, 0x2e, 0xec, 0x5d, 0xbb, 0xe1, 0x09, 0xbb, 0x1d, 0x58, 0x13, 0x8b, - 0xe9, 0xe5, 0x19, 0x0c, 0x52, 0x78, 0x6f, 0xcd, 0x13, 0x4f, 0x02, 0xb4, 0x0c, 0xb3, 0x0a, 0xe2, - 0x19, 0x90, 0xe3, 0x1f, 0x7a, 0xd6, 0x05, 0x05, 0x53, 0xb6, 0x5b, 0x12, 0x57, 0xf7, 0x0f, 0xbd, - 0x08, 0x49, 0x92, 0xc8, 0xc9, 0x18, 0x59, 0x8d, 0x90, 0x15, 0x98, 0x57, 0xc8, 0x86, 0xef, 0xed, - 0x26, 0xc1, 0x53, 0x0a, 0x5c, 0x94, 0xba, 0x35, 0xdf, 0xdb, 0x8d, 0xf0, 0x6b, 0x00, 0x5c, 0x10, - 0x26, 0xa8, 0x63, 0x13, 0x61, 0x65, 0xd4, 0x38, 0x17, 0x2a, 0x7a, 0x07, 0x55, 0xc2, 0x1d, 0x54, - 0x79, 0x1c, 0x6e, 0x31, 0x3d, 0xcc, 0x5f, 0x7f, 0x5e, 0x4e, 0xe3, 0xac, 0xb1, 0xab, 0x8a, 0xfb, - 0x13, 0x99, 0x74, 0x71, 0x6c, 0xe9, 0xf3, 0x1c, 0xcc, 0x3c, 0xa8, 0xae, 0x6d, 0x13, 0x46, 0x5a, - 0x54, 0x50, 0xc6, 0xd1, 0x9b, 0x90, 0x69, 0x91, 0x8e, 0x4d, 0x5d, 0x16, 0x58, 0xe9, 0xc5, 0xf4, - 0xf2, 0x58, 0x2d, 0xd7, 0xeb, 0x96, 0xa7, 0x1e, 0x90, 0xce, 0xfa, 0x06, 0xde, 0xc6, 0x53, 0x2d, - 0xd2, 0x59, 0x77, 0x59, 0x80, 0xde, 0x86, 0xd9, 0x76, 0xd0, 0x74, 0xbd, 0x7d, 0xdb, 0x39, 0xa4, - 0xcd, 0xa6, 0x2d, 0x77, 0xb4, 0x5a, 0xc8, 0x0c, 0x2e, 0x68, 0x45, 0x5d, 0xca, 0xa5, 0x17, 0xa8, - 0x02, 0x73, 0x72, 0x40, 0x83, 0xe8, 0x71, 0x85, 0x9e, 0x0d, 0x55, 0x31, 0x7e, 0x07, 0xe6, 0x88, - 0xc3, 0x6c, 0xb9, 0x73, 0x6c, 0x46, 0x04, 0xb5, 0x5d, 0xcf, 0xa1, 0x1d, 0xb5, 0x1a, 0xf9, 0xd5, - 0xd7, 0x06, 0x57, 0xb4, 0x4e, 0x04, 0xc1, 0x44, 0xd0, 0x0d, 0x09, 0xaa, 0xcd, 0xf7, 0xba, 0xe5, - 0x62, 0xb5, 0x8e, 0xfb, 0xa4, 0xb8, 0x48, 0x1c, 0xd6, 0x27, 0x41, 0xef, 0x01, 0x92, 0xdf, 0x10, - 0x1d, 0x3b, 0xf0, 0x0f, 0x29, 0x33, 0x9f, 0x50, 0x2b, 0x59, 0x9b, 0xeb, 0x75, 0xcb, 0x85, 0x6a, - 0x1d, 0x3f, 0xee, 0x6c, 0x4b, 0x9d, 0xa6, 0x28, 0x10, 0x87, 0x25, 0x05, 0xe8, 0x06, 0x4c, 0x4b, - 0x06, 0x6f, 0xc7, 0x16, 0x8c, 0x78, 0x5c, 0xaf, 0x6d, 0x2d, 0xdf, 0xeb, 0x96, 0xa1, 0x5a, 0xc7, - 0x5b, 0x3b, 0x8f, 0xa5, 0x14, 0x03, 0x71, 0x98, 0x79, 0x46, 0xb7, 0x60, 0x46, 0x5a, 0x90, 0xc6, - 0xbe, 0xdd, 0x74, 0x5b, 0xae, 0xd0, 0x2b, 0x5c, 0x2b, 0xf4, 0xba, 0xe5, 0x5c, 0xb5, 0x8e, 0xab, - 0x8d, 0xfd, 0x4d, 0x29, 0xc6, 0x39, 0xe2, 0xb0, 0xf0, 0x25, 0x69, 0xe4, 0xd0, 0x26, 0x39, 0x52, - 0x0b, 0xde, 0x67, 0x54, 0x97, 0xe2, 0xd0, 0x48, 0xbd, 0xa0, 0xdb, 0x90, 0x65, 0x9d, 0x9b, 0xc6, - 0x20, 0xab, 0xe6, 0xed, 0xf2, 0xe0, 0xbc, 0xe1, 0x8e, 0x36, 0xcc, 0xb0, 0xce, 0x4d, 0x6d, 0x75, - 0x1d, 0xe6, 0x95, 0x55, 0x34, 0xef, 0xfe, 0xee, 0x2e, 0xa7, 0xc2, 0x02, 0xb5, 0x11, 0x67, 0x25, - 0xce, 0xcc, 0xe1, 0x43, 0xa5, 0x40, 0x9b, 0x30, 0xc7, 0x3a, 0xab, 0x43, 0x0b, 0x95, 0x3b, 0xc3, - 0x42, 0xe1, 0x22, 0xeb, 0xac, 0xf6, 0x2f, 0xc9, 0x55, 0x98, 0x91, 0x6c, 0xbb, 0x8c, 0xfe, 0xbc, - 0x4d, 0xbd, 0xc6, 0x91, 0x35, 0xbd, 0x98, 0x5e, 0x9e, 0xc0, 0xd3, 0xac, 0xb3, 0x7a, 0x2f, 0x94, - 0xa1, 0x9f, 0xc0, 0x65, 0x46, 0x65, 0x58, 0x53, 0x7b, 0xc8, 0x0e, 0x28, 0x73, 0x7d, 0xc7, 0x6d, - 0xb8, 0xe2, 0xc8, 0x9a, 0x51, 0x9f, 0x5d, 0x1a, 0x1a, 0xa7, 0x82, 0xcb, 0x8d, 0xb5, 0xde, 0x09, - 0x7c, 0x8f, 0x7a, 0x02, 0x5f, 0x64, 0x91, 0x6c, 0x3b, 0x26, 0x40, 0xcf, 0xc1, 0x32, 0xdc, 0x0d, - 0xbf, 0xed, 0x89, 0x3e, 0xf2, 0xbc, 0x22, 0xbf, 0x3a, 0x9a, 0x7c, 0x4d, 0xc2, 0x23, 0xf6, 0x4b, - 0x2c, 0x16, 0x26, 0xe9, 0x37, 0x20, 0x2f, 0x8f, 0x96, 0xd3, 0x16, 0x47, 0x76, 0xe3, 0xa8, 0xd1, - 0xa4, 0x56, 0x61, 0x34, 0x69, 0x75, 0x6f, 0x8f, 0xd1, 0x3d, 0x22, 0xa8, 0x53, 0x6f, 0x8b, 0xa3, - 0x35, 0x09, 0xc5, 0xd3, 0x2d, 0xd2, 0x89, 0xde, 0x50, 0x15, 0x32, 0x8d, 0x17, 0xc4, 0xf3, 0x68, - 0x93, 0x5b, 0xc5, 0xc5, 0xf1, 0xe5, 0xdc, 0xea, 0x1b, 0x83, 0x24, 0x7d, 0xc7, 0xba, 0xb2, 0xa6, - 0xd1, 0x38, 0x32, 0x93, 0x87, 0x32, 0x70, 0xbd, 0x3d, 0x9b, 0x37, 0x7d, 0x91, 0x98, 0xf3, 0x59, - 0x35, 0xe7, 0xb3, 0x52, 0xf5, 0xa8, 0xe9, 0x8b, 0x78, 0xe2, 0x9f, 0xc1, 0x2b, 0x31, 0x7e, 0x70, - 0xc5, 0xd1, 0x59, 0x56, 0xfc, 0x62, 0x48, 0xda, 0xbf, 0xec, 0x6f, 0x41, 0x71, 0x87, 0x92, 0x86, - 0xef, 0x25, 0xbc, 0x98, 0x53, 0x5e, 0x14, 0xb4, 0x3c, 0xf2, 0x61, 0xe1, 0xbf, 0xc7, 0x60, 0xca, - 0x8c, 0x44, 0x9a, 0x99, 0x00, 0x14, 0x9b, 0xa5, 0xb5, 0x99, 0x96, 0xc7, 0xae, 0xaf, 0x00, 0x8a, - 0xe2, 0x4f, 0x0c, 0x1e, 0xd3, 0x23, 0x0d, 0x35, 0x31, 0x7c, 0x13, 0xe6, 0x5a, 0xae, 0x37, 0x34, - 0xc6, 0xf1, 0x33, 0xed, 0xea, 0x96, 0xeb, 0xf5, 0x0f, 0x4f, 0xb2, 0xc9, 0x55, 0xff, 0x0a, 0xc1, - 0x0c, 0x17, 0xe5, 0xa2, 0x0f, 0x9e, 0x11, 0xea, 0x91, 0x9d, 0x26, 0xb5, 0xf5, 0x20, 0x55, 0xc4, - 0xca, 0xe0, 0x69, 0x2d, 0x7c, 0xa2, 0x64, 0x77, 0x26, 0x3e, 0xf9, 0x6d, 0x39, 0xa5, 0xff, 0x2e, - 0xb5, 0x20, 0xbf, 0xee, 0x39, 0x75, 0x55, 0x82, 0xd5, 0x18, 0xf1, 0x1c, 0x74, 0x09, 0xc6, 0x5c, - 0x47, 0x4d, 0x55, 0xb6, 0x36, 0xd9, 0xeb, 0x96, 0xc7, 0x36, 0xea, 0x78, 0xcc, 0x75, 0x10, 0x82, - 0x09, 0x8f, 0x98, 0x20, 0x9e, 0xc5, 0xea, 0x19, 0xbd, 0x02, 0xe3, 0x6d, 0xd6, 0x54, 0x43, 0xcf, - 0xd6, 0xa6, 0x7a, 0xdd, 0xf2, 0xf8, 0x13, 0xbc, 0x89, 0xa5, 0x0c, 0xcd, 0xc3, 0x85, 0xa6, 0xbf, - 0xe7, 0x73, 0x6b, 0x62, 0x71, 0x7c, 0x39, 0x8b, 0xf5, 0xcb, 0x92, 0x93, 0xf8, 0xdc, 0x03, 0xdf, - 0xa1, 0x4d, 0x99, 0x50, 0x76, 0xe4, 0x77, 0xed, 0xe8, 0xa3, 0x2a, 0xa1, 0x28, 0x5f, 0x36, 0xea, - 0x78, 0x4a, 0x29, 0x37, 0x42, 0xb7, 0xc6, 0x4e, 0x74, 0x6b, 0x3c, 0x76, 0x6b, 0xe9, 0xdf, 0xc6, - 0xe0, 0xd5, 0xe8, 0x33, 0x4f, 0x29, 0x93, 0x19, 0x7d, 0x23, 0xae, 0x87, 0xd0, 0xc3, 0xa1, 0x6f, - 0xde, 0x4e, 0x7c, 0xb3, 0xf7, 0x79, 0xf9, 0x0d, 0x78, 0xfd, 0xa3, 0x9f, 0x92, 0x95, 0x7f, 0xb8, - 0xb1, 0xf2, 0xfd, 0xe7, 0xcb, 0x77, 0xef, 0xfc, 0x74, 0xe5, 0xf9, 0xdd, 0xf0, 0xf5, 0xad, 0x7f, - 0x5c, 0x7d, 0xe7, 0x9f, 0xaf, 0xfd, 0xd3, 0x47, 0xd7, 0x3a, 0x6f, 0xc4, 0xce, 0x3d, 0x84, 0x4c, - 0x4b, 0x8e, 0xc6, 0x8e, 0x5c, 0x54, 0x84, 0x6a, 0x84, 0xe7, 0x22, 0x54, 0x2c, 0x1b, 0x8e, 0xdc, - 0xbd, 0x2f, 0x08, 0x73, 0x0e, 0x09, 0xa3, 0xf6, 0x81, 0x1e, 0x80, 0x19, 0x61, 0x21, 0x94, 0x9b, - 0x71, 0x49, 0xe8, 0xae, 0xcb, 0x5a, 0x7d, 0xd0, 0x09, 0x0d, 0x0d, 0xe5, 0x06, 0xba, 0xf4, 0xaf, - 0x53, 0x50, 0x1c, 0x9c, 0x17, 0xf4, 0x3e, 0x8c, 0xbb, 0x0e, 0x57, 0xf3, 0x90, 0x5b, 0xfd, 0xf6, - 0xe0, 0x86, 0x3b, 0x65, 0x1a, 0x13, 0xf5, 0x91, 0x64, 0x40, 0xcf, 0xa0, 0x60, 0x0c, 0x23, 0x3f, - 0xc6, 0xd4, 0x2e, 0x5e, 0x18, 0x11, 0x7b, 0x0c, 0x5d, 0x0d, 0xf5, 0xba, 0xe5, 0xfc, 0xa6, 0x8f, - 0xc9, 0xb3, 0xea, 0x96, 0x91, 0xe1, 0xbc, 0x81, 0x86, 0x1e, 0x12, 0x98, 0x0b, 0x89, 0x83, 0x17, - 0x47, 0x7d, 0xf3, 0x31, 0x82, 0x7c, 0xfb, 0x83, 0x0f, 0x43, 0xf2, 0x8b, 0xbd, 0x6e, 0x79, 0xd6, - 0x90, 0xc7, 0x62, 0x3c, 0x6b, 0xd0, 0xdb, 0x2f, 0x8e, 0xc2, 0x4f, 0xdc, 0x85, 0xd9, 0xe8, 0xe4, - 0xdb, 0x41, 0x93, 0x78, 0x72, 0x25, 0xd5, 0x2c, 0xea, 0x6c, 0x1f, 0x9d, 0xfe, 0xed, 0x26, 0xf1, - 0x36, 0xea, 0xb8, 0xb0, 0xdb, 0x27, 0x90, 0xdb, 0x73, 0x32, 0x78, 0xe1, 0x0b, 0x9f, 0x5b, 0x17, - 0xd4, 0x7e, 0x37, 0x6f, 0x68, 0x19, 0x8a, 0xbc, 0x1d, 0x04, 0x3e, 0x13, 0xdc, 0x6e, 0x34, 0x09, - 0xe7, 0xf6, 0x8e, 0xaa, 0x04, 0x32, 0x38, 0x1f, 0xca, 0xd7, 0xa4, 0xb8, 0x36, 0x02, 0xd9, 0x50, - 0x05, 0xc0, 0x20, 0x72, 0x0d, 0xb5, 0xe0, 0x92, 0x43, 0x77, 0x49, 0xbb, 0x29, 0xec, 0x16, 0x69, - 0xd8, 0x41, 0x14, 0xc6, 0x4d, 0xb1, 0xf7, 0xda, 0xa9, 0xb1, 0xbe, 0x66, 0xf5, 0xba, 0xe5, 0xf9, - 0xba, 0x26, 0xe8, 0xd3, 0xe0, 0x79, 0x43, 0xfb, 0x80, 0x34, 0x12, 0x25, 0xdf, 0x55, 0x98, 0x91, - 0xf1, 0x2e, 0x8e, 0x8c, 0x59, 0x9d, 0x77, 0x5b, 0x6e, 0x1c, 0x7a, 0x15, 0x88, 0x74, 0x12, 0x20, - 0x30, 0x20, 0xd2, 0x89, 0x41, 0x8b, 0x30, 0xcd, 0x28, 0xa7, 0x82, 0xeb, 0x32, 0x56, 0x15, 0x02, - 0x19, 0x0c, 0x5a, 0x26, 0xeb, 0x57, 0xf4, 0x03, 0x98, 0x6d, 0x73, 0xca, 0xed, 0x5b, 0xab, 0xf6, - 0x8e, 0x6b, 0x2a, 0x6d, 0x95, 0xe7, 0x33, 0xb5, 0xd9, 0x5e, 0xb7, 0x3c, 0xf3, 0x84, 0x53, 0x7e, - 0x6b, 0xb5, 0xe6, 0xaa, 0x7a, 0x1b, 0xcf, 0xb4, 0x93, 0xaf, 0xd2, 0x87, 0x68, 0x06, 0x65, 0x86, - 0x55, 0x19, 0x3f, 0x83, 0xa7, 0x43, 0xe1, 0x7d, 0xdf, 0xf5, 0xd0, 0x3b, 0x80, 0x8c, 0x0f, 0x2a, - 0x93, 0x7b, 0xbe, 0xd7, 0xa0, 0x5c, 0xa5, 0xef, 0x0c, 0x2e, 0x6a, 0x8d, 0xc4, 0x6d, 0x29, 0x39, - 0x7a, 0x0e, 0x28, 0x9c, 0xea, 0x5d, 0x9f, 0xb5, 0x88, 0x50, 0xd3, 0x5c, 0x50, 0xd3, 0xbc, 0x3c, - 0x34, 0xcd, 0xba, 0xe1, 0xd9, 0x26, 0x47, 0x4d, 0x9f, 0x38, 0xf7, 0x22, 0x7c, 0x6d, 0x42, 0x1e, - 0x14, 0x3c, 0x6b, 0x98, 0x62, 0x85, 0x89, 0xc1, 0x9f, 0x4d, 0x42, 0xee, 0x41, 0x75, 0xed, 0x11, - 0x15, 0x42, 0xf6, 0x34, 0xe8, 0x2e, 0x4c, 0xb5, 0x39, 0xb5, 0x89, 0xc3, 0xcc, 0xa9, 0x1c, 0xae, - 0xde, 0x6b, 0xbe, 0xdf, 0x7c, 0x4a, 0x9a, 0x6d, 0x5a, 0x83, 0x5e, 0xb7, 0x3c, 0xf9, 0x84, 0xd3, - 0x6a, 0x1d, 0xe3, 0xc9, 0x36, 0xa7, 0x55, 0x87, 0xa1, 0xfb, 0x20, 0xcb, 0x4a, 0xbb, 0x45, 0xd8, - 0x9e, 0xab, 0x0f, 0x61, 0x6e, 0xf5, 0xca, 0x10, 0xc7, 0x93, 0x0d, 0x4f, 0xdc, 0x5a, 0xd5, 0x2c, - 0x33, 0xbd, 0x6e, 0x39, 0x5b, 0xad, 0xe3, 0x07, 0xca, 0x04, 0x67, 0x89, 0xc3, 0xf4, 0x23, 0x7a, - 0x1f, 0x0a, 0x66, 0xdf, 0xaa, 0x8a, 0xca, 0x6f, 0x0b, 0xd3, 0x3a, 0xbd, 0x32, 0x44, 0x58, 0x37, - 0x5d, 0x71, 0x6d, 0xe2, 0x37, 0xb2, 0x9b, 0x98, 0x51, 0x76, 0xb5, 0xc7, 0xda, 0x2a, 0x26, 0x6a, - 0x44, 0x44, 0x13, 0xe7, 0x21, 0x5a, 0x0b, 0x89, 0x9e, 0xc1, 0x65, 0x2e, 0x88, 0x68, 0xf3, 0xe1, - 0x12, 0xef, 0xc2, 0xd9, 0x08, 0x2f, 0x6a, 0xfb, 0xc1, 0xfa, 0xee, 0x29, 0x58, 0x86, 0x78, 0xb8, - 0xbe, 0x9b, 0xfc, 0xf2, 0x49, 0xc4, 0x97, 0xb4, 0xf5, 0x50, 0x61, 0xb7, 0x9e, 0xac, 0xb6, 0xa7, - 0x4e, 0xd8, 0x3b, 0xf1, 0xfa, 0x87, 0x95, 0xb7, 0x26, 0x8d, 0xcb, 0xef, 0xe7, 0xa3, 0xab, 0x69, - 0x7d, 0xe6, 0x2b, 0xa7, 0x11, 0xf6, 0xd5, 0x08, 0x9a, 0x76, 0xb8, 0xbc, 0xae, 0x0e, 0x96, 0xd7, - 0xd9, 0x53, 0x86, 0xfc, 0x9d, 0xdb, 0x9a, 0xa6, 0xaf, 0xf8, 0x5e, 0xf8, 0x11, 0x4c, 0x27, 0x7d, - 0x47, 0x2b, 0x70, 0xe1, 0x40, 0x3e, 0xa8, 0x6d, 0x7c, 0x4a, 0x8b, 0xa1, 0x51, 0x0b, 0x1b, 0x80, - 0x86, 0x3d, 0x45, 0xb7, 0xfa, 0x49, 0xbe, 0xa4, 0x24, 0xd2, 0xd8, 0xa5, 0xff, 0xca, 0x42, 0x46, - 0xce, 0x80, 0x20, 0x82, 0x22, 0x0c, 0xa8, 0xd1, 0x66, 0x8c, 0xca, 0x25, 0x8d, 0x63, 0x65, 0xfa, - 0x2c, 0xb1, 0xd2, 0x9c, 0x5c, 0x63, 0x9e, 0x08, 0x8a, 0x58, 0x06, 0x06, 0xee, 0x32, 0xea, 0x24, - 0x39, 0xc7, 0xce, 0xc1, 0x69, 0xcc, 0x13, 0x9c, 0xdf, 0x83, 0x69, 0x7d, 0x17, 0xa6, 0xe3, 0xbf, - 0x49, 0x70, 0x17, 0x07, 0xd9, 0x54, 0x16, 0xc0, 0x39, 0x0d, 0x55, 0x2f, 0xa3, 0x52, 0xef, 0xc4, - 0xff, 0x4b, 0xea, 0x7d, 0x0e, 0x0b, 0xd1, 0xdd, 0x83, 0xcb, 0x5a, 0xd4, 0xb1, 0xa3, 0x4a, 0x99, - 0x08, 0x73, 0xdc, 0x4e, 0xbb, 0x5b, 0x98, 0x50, 0xf7, 0x0a, 0x97, 0xc3, 0x3b, 0x0a, 0x45, 0x51, - 0x37, 0x0c, 0x55, 0x81, 0xde, 0x05, 0x4b, 0xd1, 0x3b, 0xf4, 0xc0, 0x36, 0x47, 0x2f, 0xba, 0x5c, - 0xd1, 0x77, 0x21, 0x73, 0x52, 0x5f, 0xa7, 0x07, 0x8f, 0x94, 0xd6, 0xdc, 0xb2, 0x60, 0xb8, 0x18, - 0xf7, 0x1a, 0xc9, 0x53, 0x3a, 0xa5, 0x06, 0x5d, 0x1a, 0x2a, 0x09, 0x4c, 0x63, 0xa1, 0x0f, 0x25, - 0x9e, 0x0b, 0xfa, 0xde, 0xf5, 0x21, 0xa5, 0x70, 0x25, 0xa0, 0x9e, 0x23, 0x69, 0x49, 0x10, 0x34, - 0xdd, 0x86, 0x0a, 0x18, 0xd1, 0x70, 0xcd, 0x31, 0x1b, 0xee, 0xc5, 0x62, 0x6c, 0x38, 0x2e, 0xbc, - 0x60, 0x88, 0x46, 0xe8, 0xd0, 0x3a, 0x14, 0x7f, 0xde, 0xa6, 0x6d, 0xea, 0xd8, 0x8c, 0xf2, 0xc0, - 0xf7, 0x38, 0xe5, 0x56, 0x56, 0x75, 0x68, 0xa3, 0x96, 0x6a, 0xcd, 0x6f, 0xb5, 0x88, 0xe7, 0xe0, - 0x82, 0xb6, 0xc1, 0xa1, 0x89, 0xa4, 0x09, 0xbd, 0x55, 0xa7, 0x8f, 0x0b, 0x6e, 0xc1, 0x97, 0xd3, - 0x18, 0x1b, 0x6c, 0x4c, 0xd0, 0xdf, 0x01, 0x32, 0xde, 0xa8, 0x64, 0x48, 0x1a, 0x0d, 0x1a, 0xe8, - 0xb4, 0x3c, 0x62, 0xa8, 0xe1, 0x79, 0xaa, 0xc8, 0xfc, 0x58, 0x55, 0x50, 0x6c, 0x06, 0x13, 0x4b, - 0xd0, 0x03, 0x98, 0x0f, 0x3d, 0x53, 0x9c, 0xc6, 0x3d, 0x95, 0xc4, 0x47, 0xdc, 0xb7, 0x49, 0x4b, - 0xe3, 0x0e, 0x46, 0xc6, 0x30, 0x21, 0x43, 0x37, 0x60, 0x9e, 0x75, 0xec, 0x43, 0xd7, 0x73, 0xfc, - 0x43, 0x6e, 0x93, 0x03, 0xe2, 0x36, 0x65, 0x27, 0x63, 0x52, 0x3b, 0x62, 0x9d, 0x67, 0x5a, 0x55, - 0x0d, 0x35, 0x0b, 0xff, 0x99, 0x06, 0x48, 0xf8, 0xb3, 0x04, 0x53, 0x81, 0x4e, 0xc8, 0xea, 0xc4, - 0x4f, 0xd7, 0x32, 0xbd, 0xcf, 0xcb, 0x13, 0x41, 0xae, 0xf3, 0x1a, 0x0e, 0x15, 0xe8, 0x07, 0x30, - 0x15, 0xba, 0x39, 0xf6, 0xa5, 0x6e, 0x9a, 0xf3, 0x1b, 0x5a, 0xa0, 0x77, 0xcf, 0x7e, 0xa1, 0xa8, - 0x2d, 0x15, 0xdc, 0xa4, 0xfe, 0x7f, 0xb1, 0x20, 0x1b, 0x95, 0xd8, 0xe8, 0xbd, 0x64, 0x29, 0x7e, - 0xed, 0xc4, 0x52, 0xfc, 0x94, 0x1a, 0x7c, 0x0d, 0xa0, 0xc1, 0x28, 0x31, 0x77, 0x7f, 0x63, 0xe7, - 0xb9, 0xfb, 0x33, 0x76, 0x55, 0x21, 0x49, 0xda, 0x81, 0x13, 0x92, 0x8c, 0x9f, 0x87, 0xc4, 0xd8, - 0x55, 0x45, 0xd4, 0x97, 0x4d, 0x24, 0xda, 0xc5, 0x45, 0xc8, 0x39, 0x94, 0x37, 0x98, 0x1b, 0xc8, - 0x33, 0xa1, 0xc2, 0x47, 0x16, 0x27, 0x45, 0x68, 0x03, 0x80, 0x08, 0xc1, 0xdc, 0x9d, 0xb6, 0xa0, - 0xdc, 0x9a, 0x54, 0x3b, 0xfa, 0xad, 0x13, 0x27, 0xa2, 0x52, 0x8d, 0xb0, 0xeb, 0x9e, 0x60, 0x47, - 0x38, 0x61, 0x8c, 0x7e, 0x06, 0x39, 0x13, 0x0b, 0x6d, 0x39, 0xa9, 0x53, 0xe7, 0xef, 0x6f, 0xd4, - 0x5d, 0x5d, 0x28, 0xaf, 0x73, 0x0c, 0x07, 0x21, 0x86, 0xa3, 0x1a, 0x20, 0x4e, 0x99, 0x0a, 0xd6, - 0x01, 0xf3, 0x77, 0xdd, 0x26, 0x95, 0x1d, 0x43, 0x46, 0x75, 0x0c, 0xea, 0x8e, 0xf1, 0x91, 0xd6, - 0x6e, 0x6b, 0xe5, 0x46, 0x1d, 0x17, 0x79, 0xbf, 0xc4, 0x41, 0xb7, 0xe1, 0x92, 0xb9, 0xbe, 0xb6, - 0xa5, 0x8e, 0x32, 0x75, 0xdd, 0x4d, 0x39, 0x57, 0xa9, 0x37, 0x8b, 0xe7, 0x8d, 0xf6, 0x91, 0x52, - 0x56, 0xb5, 0x0e, 0xfd, 0x10, 0x16, 0x92, 0x01, 0x6a, 0xc0, 0x12, 0x94, 0xa5, 0x95, 0x40, 0xf4, - 0x5b, 0x57, 0x60, 0x4e, 0x1d, 0xcb, 0x01, 0xb3, 0x9c, 0x32, 0x9b, 0x95, 0xaa, 0x7e, 0xfc, 0x3d, - 0xc8, 0x36, 0x7d, 0x4d, 0xc4, 0xad, 0x69, 0xb5, 0x1e, 0xcb, 0x27, 0xaf, 0xc7, 0x66, 0x08, 0xd5, - 0xcb, 0x11, 0x9b, 0x8e, 0xec, 0x83, 0x66, 0xce, 0xdc, 0x07, 0xe5, 0x47, 0xf6, 0x41, 0x23, 0xb2, - 0x5e, 0xe1, 0x9b, 0x6c, 0x38, 0x8b, 0xdf, 0x74, 0xc3, 0x39, 0x7b, 0x8e, 0x86, 0xf3, 0xe4, 0x26, - 0x10, 0xfd, 0x4d, 0x9a, 0xc0, 0xb9, 0xb3, 0x34, 0x81, 0xf3, 0x67, 0x68, 0x02, 0x2f, 0x9e, 0xad, - 0x09, 0xbc, 0xf4, 0x55, 0x9b, 0xc0, 0xcb, 0x67, 0x6e, 0x02, 0xad, 0x13, 0x9a, 0xc0, 0x77, 0x21, - 0xcb, 0x7c, 0x5f, 0xd8, 0x2a, 0xcc, 0xbf, 0xa2, 0x66, 0xd7, 0x1a, 0x2a, 0x65, 0x7d, 0x5f, 0xc8, - 0x18, 0x8f, 0x33, 0xcc, 0x3c, 0xa1, 0xa7, 0x30, 0xe9, 0x51, 0x21, 0xd7, 0x75, 0x41, 0x25, 0x9e, - 0xbb, 0x7f, 0xea, 0x96, 0x57, 0xcf, 0xf5, 0xe3, 0xd5, 0x16, 0x15, 0x1b, 0xf5, 0x5e, 0xb7, 0x7c, - 0x41, 0x3d, 0xe0, 0x0b, 0x1e, 0x15, 0xea, 0xb2, 0x69, 0x5a, 0xae, 0x38, 0x37, 0xd5, 0xbd, 0xf5, - 0xea, 0xe8, 0xc4, 0x93, 0x68, 0x00, 0xf4, 0xaf, 0x01, 0x09, 0x01, 0xce, 0xb5, 0x48, 0x23, 0xea, - 0x37, 0xd7, 0x20, 0xab, 0x08, 0x65, 0x72, 0xb7, 0xae, 0x8c, 0x1e, 0x5f, 0x98, 0xfc, 0x6b, 0xd3, - 0xbd, 0x6e, 0x39, 0x2a, 0xad, 0x71, 0x46, 0xf2, 0xa8, 0x22, 0xfb, 0x26, 0x4c, 0x71, 0x9d, 0xea, - 0xac, 0xd7, 0x14, 0xc5, 0xe5, 0x13, 0x32, 0x21, 0x0e, 0x71, 0xe8, 0x3d, 0x08, 0x0b, 0x12, 0x3b, - 0x34, 0x2d, 0x9d, 0x6e, 0x9a, 0x37, 0xf8, 0xf0, 0x57, 0xc2, 0x6b, 0x90, 0x8f, 0xea, 0x47, 0xb5, - 0x88, 0x56, 0x59, 0x55, 0x8d, 0xd3, 0xa6, 0x6a, 0x54, 0x0b, 0x88, 0xde, 0x84, 0x42, 0x9b, 0x53, - 0x27, 0x46, 0x71, 0x6b, 0x71, 0x71, 0x7c, 0x79, 0x46, 0x6d, 0x1d, 0x27, 0x84, 0x71, 0x89, 0x53, - 0x6c, 0xf1, 0x9e, 0xb0, 0x5e, 0x8f, 0x7f, 0x90, 0x8b, 0x36, 0x04, 0xfa, 0xae, 0xc1, 0xb1, 0x8f, - 0x4d, 0xa3, 0x78, 0xc3, 0x5a, 0x52, 0x3f, 0xba, 0x14, 0x7b, 0xdd, 0xf2, 0xf4, 0x26, 0xe1, 0x02, - 0xdf, 0x57, 0x4d, 0xe0, 0x0d, 0xed, 0x08, 0xfe, 0x58, 0xbf, 0x0d, 0x1b, 0xde, 0xb4, 0xae, 0x8e, - 0x34, 0xbc, 0xd9, 0x67, 0x78, 0x13, 0x7d, 0x04, 0xaf, 0x0e, 0xd6, 0xc9, 0x8c, 0x36, 0xa8, 0x7b, - 0xa0, 0x53, 0xf4, 0xb5, 0xf3, 0xd4, 0xe1, 0x51, 0x31, 0x8d, 0x0d, 0x43, 0x55, 0x9e, 0xb8, 0x9c, - 0xfe, 0x99, 0x4b, 0xef, 0x81, 0x37, 0x4e, 0x08, 0x74, 0x12, 0xa2, 0xd7, 0x1d, 0x82, 0xe8, 0x19, - 0xad, 0x00, 0xda, 0x51, 0xf7, 0x19, 0x47, 0xb2, 0x16, 0x6f, 0x50, 0x4f, 0x90, 0x3d, 0x6a, 0xbd, - 0xb9, 0x98, 0x5e, 0x1e, 0xc3, 0xb3, 0x46, 0xb3, 0x1d, 0x29, 0xd0, 0xb7, 0xa0, 0x10, 0xf5, 0x10, - 0xe6, 0x86, 0xe2, 0x5b, 0x8b, 0xe9, 0xe5, 0x0b, 0x38, 0x1f, 0x8a, 0xcd, 0xcd, 0x03, 0x91, 0x87, - 0x54, 0x5a, 0xd9, 0xc4, 0x61, 0xe6, 0x3e, 0x9b, 0x5b, 0xcb, 0x2a, 0x07, 0x0d, 0x45, 0x37, 0x7d, - 0xb5, 0x6d, 0x6e, 0x60, 0x74, 0x06, 0xc6, 0xca, 0xb8, 0x5a, 0xc7, 0x5a, 0xc7, 0xe5, 0xc9, 0x56, - 0x12, 0x87, 0x19, 0x09, 0xaa, 0x43, 0xde, 0x7c, 0x22, 0xa4, 0x7f, 0xeb, 0x0c, 0xf4, 0x78, 0x46, - 0x1b, 0x85, 0x2c, 0xf7, 0xc1, 0x30, 0x47, 0xdd, 0x02, 0xb7, 0xde, 0x56, 0x3c, 0xe5, 0xa1, 0x66, - 0x35, 0x1c, 0xa2, 0x61, 0x2a, 0x68, 0xc3, 0x50, 0xcc, 0x65, 0x1b, 0x62, 0x2a, 0xf2, 0x51, 0x5d, - 0x08, 0xb7, 0xbe, 0xad, 0x78, 0xcf, 0xd6, 0x86, 0x68, 0xa2, 0x11, 0x2a, 0x8e, 0x3e, 0x00, 0x48, - 0xdc, 0x67, 0xbd, 0x73, 0xbe, 0xfb, 0x2c, 0x9c, 0xb0, 0x45, 0x04, 0xf2, 0x01, 0xf3, 0x0f, 0x5c, - 0x79, 0x1e, 0x29, 0x93, 0xd1, 0x6e, 0x45, 0x65, 0xb1, 0x3b, 0x32, 0x52, 0x6f, 0xc7, 0x9a, 0xf3, - 0x5c, 0x83, 0xcf, 0x24, 0x18, 0x37, 0x1c, 0x54, 0x87, 0xd9, 0x48, 0x20, 0x83, 0x85, 0x43, 0x04, - 0xb1, 0x2a, 0x26, 0x52, 0x0c, 0xee, 0xf9, 0x47, 0xea, 0x1f, 0x2b, 0x70, 0x31, 0x69, 0x51, 0x27, - 0x82, 0x2c, 0xfc, 0x08, 0x0a, 0x03, 0xe5, 0x22, 0x2a, 0xc2, 0xf8, 0x3e, 0xd5, 0x3f, 0x0b, 0x65, - 0xb1, 0x7c, 0x44, 0xf3, 0xe1, 0x65, 0x83, 0xfe, 0x95, 0x43, 0xbf, 0xdc, 0x19, 0xfb, 0x5e, 0x7a, - 0xe1, 0x29, 0xe4, 0xfb, 0xab, 0x9b, 0x11, 0xd6, 0x95, 0xa4, 0xf5, 0x88, 0x20, 0x1a, 0x12, 0x24, - 0x78, 0x4d, 0x1f, 0xf0, 0x01, 0x40, 0x54, 0x45, 0x71, 0x74, 0x07, 0x72, 0xf1, 0x3f, 0xc6, 0xc8, - 0x7e, 0x60, 0x5c, 0xdd, 0x6a, 0x9d, 0x54, 0x76, 0x61, 0xa0, 0x91, 0xed, 0xd2, 0xcf, 0xe0, 0xd2, - 0x9a, 0xaa, 0xe4, 0x63, 0xb5, 0x69, 0x54, 0x6a, 0x00, 0x31, 0xab, 0x69, 0x32, 0x4e, 0x26, 0x4d, - 0x74, 0x16, 0xd9, 0x88, 0x7e, 0xe9, 0xdf, 0xd3, 0x70, 0xe9, 0x89, 0xaa, 0xf1, 0xbf, 0x09, 0x7a, - 0x74, 0x17, 0x20, 0xfe, 0xd7, 0x99, 0x13, 0xdb, 0x97, 0x7b, 0x12, 0xf2, 0x80, 0xf0, 0x7d, 0xd3, - 0x50, 0x65, 0x77, 0x43, 0xc1, 0xd2, 0xff, 0xa4, 0x61, 0xee, 0x7d, 0x2a, 0x86, 0x9c, 0x7b, 0x0c, - 0xf9, 0xd8, 0x39, 0xfb, 0xab, 0x37, 0x59, 0xd3, 0x34, 0xd6, 0xf3, 0xaf, 0xef, 0xee, 0xff, 0xa6, - 0xe1, 0xe2, 0xa6, 0xcb, 0x63, 0x7f, 0x79, 0xe8, 0xf0, 0x87, 0x50, 0x48, 0x06, 0x80, 0xd8, 0xe3, - 0x37, 0x4f, 0x39, 0xfa, 0xa3, 0x7d, 0xce, 0x93, 0x24, 0xe2, 0xeb, 0x7b, 0x2d, 0x0f, 0x89, 0xcf, - 0x1c, 0xca, 0xcc, 0x2f, 0x52, 0xfa, 0x45, 0xfd, 0xe0, 0xa7, 0xfe, 0x6b, 0x41, 0xff, 0x57, 0x8c, - 0x7e, 0x91, 0x6d, 0x60, 0x20, 0xd3, 0x81, 0xfe, 0x1f, 0x18, 0xf5, 0xbc, 0xf4, 0xab, 0x34, 0xcc, - 0x3d, 0x1a, 0xb1, 0x48, 0xdf, 0x85, 0xc9, 0xb3, 0xee, 0x1e, 0xed, 0x93, 0x81, 0x7f, 0xed, 0x11, - 0xbd, 0x7d, 0x0f, 0x20, 0x4e, 0x6e, 0x68, 0x16, 0x66, 0xb6, 0x1f, 0x3e, 0x5b, 0xc7, 0xf6, 0x93, - 0xad, 0x1f, 0x6f, 0x3d, 0x7c, 0xb6, 0x55, 0x4c, 0xc5, 0xa2, 0x5a, 0xf5, 0xf1, 0xe3, 0x75, 0xfc, - 0x61, 0x31, 0x8d, 0x10, 0xe4, 0xb5, 0x68, 0xfd, 0xef, 0x1f, 0xaf, 0xe3, 0xad, 0xea, 0x66, 0x71, - 0xac, 0xf6, 0x1f, 0xe9, 0x4f, 0x5f, 0x96, 0xd2, 0x9f, 0xbd, 0x2c, 0xa5, 0xff, 0xf8, 0xb2, 0x94, - 0xfa, 0xf3, 0xcb, 0x52, 0xea, 0x2f, 0x2f, 0x4b, 0xa9, 0xbf, 0xbe, 0x2c, 0xa5, 0xbe, 0x78, 0x59, - 0x4a, 0xff, 0xa2, 0x57, 0x4a, 0xff, 0xb2, 0x57, 0x4a, 0xfd, 0xae, 0x57, 0x4a, 0xff, 0xbe, 0x57, - 0x4a, 0x7d, 0xd2, 0x2b, 0xa5, 0xfe, 0xd0, 0x2b, 0xa5, 0x3e, 0xed, 0x95, 0xd2, 0x9f, 0xf5, 0x4a, - 0xe9, 0x3f, 0xf6, 0x4a, 0xa9, 0x3f, 0xf7, 0x4a, 0xe9, 0xbf, 0xf4, 0x4a, 0xa9, 0xbf, 0xf6, 0x4a, - 0xe9, 0x2f, 0x7a, 0xa5, 0xd4, 0x2f, 0x8e, 0x4b, 0xa9, 0x5f, 0x1e, 0x97, 0xd2, 0xbf, 0x3e, 0x2e, - 0xa5, 0x7e, 0x73, 0x5c, 0x4a, 0xff, 0xf6, 0xb8, 0x94, 0xfa, 0xdd, 0x71, 0x29, 0xf5, 0xfb, 0xe3, - 0x52, 0xfa, 0x93, 0xe3, 0x52, 0xfa, 0x0f, 0xc7, 0xa5, 0xf4, 0x4f, 0xde, 0x39, 0x6b, 0x55, 0x29, - 0xbc, 0x60, 0x67, 0x67, 0x52, 0xcd, 0xc8, 0xad, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x17, 0x83, - 0x1b, 0x5f, 0x8f, 0x27, 0x00, 0x00, + golang_proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_f29faf389d9d861a) +} + +var fileDescriptor_end_device_f29faf389d9d861a = []byte{ + // 3549 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5a, 0x4b, 0x6c, 0x23, 0xc7, + 0x99, 0x66, 0x53, 0x1a, 0x89, 0x2c, 0x52, 0x7c, 0x94, 0x34, 0x33, 0x6d, 0x79, 0x4c, 0xca, 0x9a, + 0xb1, 0x43, 0x3b, 0x16, 0x35, 0xa3, 0x19, 0xe7, 0x31, 0x49, 0x30, 0x26, 0x45, 0x8d, 0x2d, 0x47, + 0xa3, 0xd1, 0xd6, 0xbc, 0xd6, 0x49, 0xc6, 0x8d, 0x12, 0xbb, 0x44, 0xb5, 0x45, 0x76, 0x77, 0xaa, + 0x8a, 0x12, 0xb5, 0x0f, 0x20, 0x97, 0x05, 0x72, 0x4b, 0x0e, 0xbb, 0x40, 0x2e, 0x0b, 0x04, 0x8b, + 0x5d, 0x20, 0x58, 0xec, 0x21, 0x47, 0x1f, 0x73, 0xf4, 0x6d, 0x7d, 0x0c, 0x72, 0xe0, 0x64, 0xa8, + 0x4b, 0x8e, 0x01, 0xf6, 0xe2, 0xe3, 0xa2, 0x1e, 0xfd, 0xe0, 0x43, 0xb2, 0x64, 0xaf, 0xf7, 0x22, + 0x74, 0xff, 0xff, 0xf7, 0x7f, 0xfd, 0xd7, 0xeb, 0x7f, 0x14, 0x05, 0x96, 0xdb, 0x1e, 0xc5, 0x47, + 0xd8, 0x5d, 0x61, 0x1c, 0x37, 0x0f, 0x56, 0xb1, 0xef, 0xac, 0x12, 0xd7, 0xb6, 0x6c, 0x72, 0xe8, + 0x34, 0x49, 0xd5, 0xa7, 0x1e, 0xf7, 0x60, 0x8e, 0x73, 0xb7, 0xaa, 0x71, 0xd5, 0xc3, 0xdb, 0x8b, + 0x2b, 0x2d, 0x87, 0xef, 0x77, 0x77, 0xab, 0x4d, 0xaf, 0xb3, 0xda, 0xf2, 0x5a, 0xde, 0xaa, 0x84, + 0xed, 0x76, 0xf7, 0xe4, 0x9b, 0x7c, 0x91, 0x4f, 0xca, 0x7c, 0xf1, 0x3b, 0x31, 0x78, 0xe7, 0xc8, + 0xe1, 0x07, 0xde, 0xd1, 0x6a, 0xcb, 0x5b, 0x91, 0xca, 0x95, 0x43, 0xdc, 0x76, 0x6c, 0xcc, 0x3d, + 0xca, 0x56, 0xc3, 0x47, 0x6d, 0x77, 0xad, 0xe5, 0x79, 0xad, 0x36, 0x91, 0x3e, 0x61, 0xd7, 0xf5, + 0x38, 0xe6, 0x8e, 0xe7, 0x32, 0xad, 0x2d, 0x69, 0x6d, 0xf8, 0x6d, 0xbb, 0x4b, 0x25, 0x40, 0xeb, + 0x97, 0x46, 0xf5, 0x7b, 0x0e, 0x69, 0xdb, 0x56, 0x07, 0xb3, 0x83, 0x11, 0xfe, 0x10, 0xc1, 0x38, + 0xed, 0x36, 0xb9, 0xd6, 0x96, 0x47, 0xb5, 0xdc, 0xe9, 0x10, 0xc6, 0x71, 0xc7, 0x3f, 0xcd, 0x81, + 0x23, 0x8a, 0x7d, 0x9f, 0xd0, 0xc0, 0xc1, 0xeb, 0xe3, 0x33, 0xeb, 0xd8, 0xc4, 0xe5, 0xce, 0x9e, + 0x13, 0x81, 0xae, 0x8d, 0x83, 0x3e, 0xf1, 0x1c, 0xf7, 0x74, 0xed, 0x01, 0x39, 0x0e, 0x6c, 0xcb, + 0xe3, 0xda, 0x60, 0x91, 0xf4, 0x14, 0x8c, 0x03, 0x3a, 0x84, 0x31, 0xdc, 0x22, 0xec, 0x2c, 0x04, + 0xc7, 0x36, 0xe6, 0x58, 0x21, 0x96, 0x7f, 0x35, 0x05, 0x66, 0x1f, 0x11, 0xc6, 0x1c, 0xcf, 0x85, + 0xcf, 0x40, 0xca, 0x26, 0x87, 0x16, 0xb6, 0x6d, 0x6a, 0x26, 0x97, 0x8c, 0x4a, 0xb6, 0xfe, 0xc3, + 0xcf, 0xfa, 0xe5, 0xc4, 0x9f, 0xfa, 0xe5, 0x3b, 0x2d, 0xaf, 0xca, 0xf7, 0x09, 0xdf, 0x77, 0xdc, + 0x16, 0xab, 0xba, 0x84, 0x1f, 0x79, 0xf4, 0x60, 0x75, 0x98, 0xdc, 0x3f, 0x68, 0xad, 0xf2, 0x63, + 0x9f, 0xb0, 0x6a, 0x83, 0x1c, 0xd6, 0x6c, 0x9b, 0xa2, 0x59, 0x5b, 0x3d, 0xc0, 0xef, 0x83, 0x69, + 0x31, 0x2e, 0x73, 0x6a, 0xc9, 0xa8, 0x64, 0xd6, 0x5e, 0xad, 0x0e, 0xef, 0xb7, 0xaa, 0xfe, 0xfe, + 0x8f, 0xc9, 0x31, 0xab, 0xa7, 0xc4, 0x17, 0x3f, 0xef, 0x97, 0x0d, 0x24, 0x4d, 0xe0, 0xeb, 0x60, + 0xae, 0x8d, 0x19, 0xb7, 0xf6, 0xac, 0xa6, 0xcb, 0xad, 0xae, 0x6f, 0x4e, 0x2f, 0x19, 0x95, 0x39, + 0x04, 0x84, 0xf0, 0xfe, 0xba, 0xcb, 0x9f, 0xf8, 0xb0, 0x02, 0x8a, 0x12, 0xe2, 0x6a, 0x90, 0xed, + 0x1d, 0xb9, 0xe6, 0x25, 0x09, 0x93, 0xb6, 0xdb, 0x02, 0xd7, 0xf0, 0x8e, 0xdc, 0x10, 0x89, 0xe3, + 0xc8, 0x99, 0x08, 0x59, 0x0b, 0x91, 0x55, 0xb0, 0x20, 0x91, 0x4d, 0xcf, 0xdd, 0x8b, 0x83, 0x67, + 0x25, 0xb8, 0x20, 0x74, 0xeb, 0x9e, 0xbb, 0x17, 0xe2, 0xd7, 0x01, 0x60, 0x1c, 0x53, 0x4e, 0x6c, + 0x0b, 0x73, 0x33, 0x25, 0xc7, 0xb9, 0x58, 0x55, 0x3b, 0xa8, 0x1a, 0xec, 0xa0, 0xea, 0xe3, 0x60, + 0x8b, 0xa9, 0x61, 0xfe, 0xfa, 0x45, 0xd9, 0x40, 0x69, 0x6d, 0x57, 0xe3, 0x1f, 0x4e, 0xa7, 0x8c, + 0x42, 0x72, 0xf9, 0x45, 0x06, 0xcc, 0x3d, 0xa8, 0xad, 0xef, 0x60, 0x8a, 0x3b, 0x84, 0x13, 0xca, + 0xe0, 0x9b, 0x20, 0xd5, 0xc1, 0x3d, 0x8b, 0x38, 0xd4, 0x37, 0x8d, 0x25, 0xa3, 0x92, 0xac, 0x67, + 0x06, 0xfd, 0xf2, 0xec, 0x03, 0xdc, 0xdb, 0xd8, 0x44, 0x3b, 0x68, 0xb6, 0x83, 0x7b, 0x1b, 0x0e, + 0xf5, 0xe1, 0xdb, 0xa0, 0xd8, 0xf5, 0xdb, 0x8e, 0x7b, 0x60, 0xd9, 0x47, 0xa4, 0xdd, 0xb6, 0xc4, + 0x8e, 0x96, 0x0b, 0x99, 0x42, 0x79, 0xa5, 0x68, 0x08, 0xb9, 0xf0, 0x02, 0x56, 0xc1, 0xbc, 0x18, + 0xd0, 0x28, 0x7a, 0x4a, 0xa2, 0x8b, 0x81, 0x2a, 0xc2, 0xef, 0x82, 0x79, 0x6c, 0x53, 0x4b, 0xec, + 0x1c, 0x8b, 0x62, 0x4e, 0x2c, 0xc7, 0xb5, 0x49, 0x4f, 0xae, 0x46, 0x6e, 0xed, 0xb5, 0xd1, 0x15, + 0x6d, 0x60, 0x8e, 0x11, 0xe6, 0x64, 0x53, 0x80, 0xea, 0x0b, 0x83, 0x7e, 0xb9, 0x50, 0x6b, 0xa0, + 0x21, 0x29, 0x2a, 0x60, 0x9b, 0x0e, 0x49, 0xe0, 0x7b, 0x00, 0x8a, 0x6f, 0xf0, 0x9e, 0xe5, 0x7b, + 0x47, 0x84, 0xea, 0x4f, 0xc8, 0x95, 0xac, 0xcf, 0x0f, 0xfa, 0xe5, 0x7c, 0xad, 0x81, 0x1e, 0xf7, + 0x76, 0x84, 0x4e, 0x51, 0xe4, 0xb1, 0x4d, 0xe3, 0x02, 0x78, 0x13, 0x64, 0x05, 0x83, 0xbb, 0x6b, + 0x71, 0x8a, 0x5d, 0xa6, 0xd6, 0xb6, 0x9e, 0x1b, 0xf4, 0xcb, 0xa0, 0xd6, 0x40, 0xdb, 0xbb, 0x8f, + 0x85, 0x14, 0x01, 0x6c, 0x53, 0xfd, 0x0c, 0x6f, 0x83, 0x39, 0x61, 0x81, 0x9b, 0x07, 0x56, 0xdb, + 0xe9, 0x38, 0x5c, 0xad, 0x70, 0x3d, 0x3f, 0xe8, 0x97, 0x33, 0xb5, 0x06, 0xaa, 0x35, 0x0f, 0xb6, + 0x84, 0x18, 0x65, 0xb0, 0x4d, 0x83, 0x97, 0xb8, 0x91, 0x4d, 0xda, 0xf8, 0x58, 0x2e, 0xf8, 0x90, + 0x51, 0x43, 0x88, 0x03, 0x23, 0xf9, 0x02, 0xef, 0x80, 0x34, 0xed, 0xdd, 0xd2, 0x06, 0x69, 0x39, + 0x6f, 0x57, 0x47, 0xe7, 0x0d, 0xf5, 0x94, 0x61, 0x8a, 0xf6, 0x6e, 0x29, 0xab, 0x55, 0xb0, 0x20, + 0xad, 0xc2, 0x79, 0xf7, 0xf6, 0xf6, 0x18, 0xe1, 0x26, 0x90, 0x1b, 0xb1, 0x28, 0x70, 0x7a, 0x0e, + 0x1f, 0x4a, 0x05, 0xdc, 0x02, 0xf3, 0xb4, 0xb7, 0x36, 0xb6, 0x50, 0x99, 0x73, 0x2c, 0x14, 0x2a, + 0xd0, 0xde, 0xda, 0xf0, 0x92, 0x5c, 0x07, 0x73, 0x82, 0x6d, 0x8f, 0x92, 0x9f, 0x77, 0x89, 0xdb, + 0x3c, 0x36, 0xb3, 0x4b, 0x46, 0x65, 0x1a, 0x65, 0x69, 0x6f, 0xed, 0x7e, 0x20, 0x83, 0x3f, 0x01, + 0x57, 0x29, 0x11, 0x61, 0x4d, 0xee, 0x21, 0xcb, 0x27, 0xd4, 0xf1, 0x6c, 0xa7, 0xe9, 0xf0, 0x63, + 0x73, 0x4e, 0x7e, 0x76, 0x79, 0x6c, 0x9c, 0x12, 0x2e, 0x36, 0xd6, 0x46, 0xcf, 0xf7, 0x5c, 0xe2, + 0x72, 0x74, 0x99, 0x86, 0xb2, 0x9d, 0x88, 0x00, 0x3e, 0x07, 0xa6, 0xe6, 0x6e, 0x7a, 0x5d, 0x97, + 0x0f, 0x91, 0xe7, 0x24, 0xf9, 0xf5, 0xc9, 0xe4, 0xeb, 0x02, 0x1e, 0xb2, 0x5f, 0xa1, 0x91, 0x30, + 0x4e, 0xbf, 0x09, 0x72, 0xe2, 0x68, 0xd9, 0x5d, 0x7e, 0x6c, 0x35, 0x8f, 0x9b, 0x6d, 0x62, 0xe6, + 0x27, 0x93, 0xd6, 0x5a, 0x2d, 0x4a, 0x5a, 0x98, 0x13, 0xbb, 0xd1, 0xe5, 0xc7, 0xeb, 0x02, 0x8a, + 0xb2, 0x1d, 0xdc, 0x0b, 0xdf, 0x60, 0x0d, 0xa4, 0x9a, 0xfb, 0xd8, 0x75, 0x49, 0x9b, 0x99, 0x85, + 0xa5, 0xa9, 0x4a, 0x66, 0xed, 0x8d, 0x51, 0x92, 0xa1, 0x63, 0x5d, 0x5d, 0x57, 0x68, 0x14, 0x9a, + 0x89, 0x43, 0xe9, 0x3b, 0x6e, 0xcb, 0x62, 0x6d, 0x8f, 0xc7, 0xe6, 0xbc, 0x28, 0xe7, 0xbc, 0x28, + 0x54, 0x8f, 0xda, 0x1e, 0x8f, 0x26, 0xfe, 0x19, 0x78, 0x25, 0xc2, 0x8f, 0xae, 0x38, 0x3c, 0xcf, + 0x8a, 0x5f, 0x0e, 0x48, 0x87, 0x97, 0xfd, 0x2d, 0x50, 0xd8, 0x25, 0xb8, 0xe9, 0xb9, 0x31, 0x2f, + 0xe6, 0xa5, 0x17, 0x79, 0x25, 0x0f, 0x7d, 0x58, 0xfc, 0xcf, 0x24, 0x98, 0xd5, 0x23, 0x11, 0x66, + 0x3a, 0x00, 0x45, 0x66, 0x86, 0x32, 0x53, 0xf2, 0xc8, 0xf5, 0x15, 0x00, 0xc3, 0xf8, 0x13, 0x81, + 0x93, 0x6a, 0xa4, 0x81, 0x26, 0x82, 0x6f, 0x81, 0xf9, 0x8e, 0xe3, 0x8e, 0x8d, 0x71, 0xea, 0x5c, + 0xbb, 0xba, 0xe3, 0xb8, 0xc3, 0xc3, 0x13, 0x6c, 0x62, 0xd5, 0xbf, 0x42, 0x30, 0x43, 0x05, 0xb1, + 0xe8, 0xa3, 0x67, 0x84, 0xb8, 0x78, 0xb7, 0x4d, 0x2c, 0x35, 0x48, 0x19, 0xb1, 0x52, 0x28, 0xab, + 0x84, 0x4f, 0xa4, 0xec, 0xee, 0xf4, 0xa7, 0xbf, 0x2d, 0x27, 0xd4, 0xdf, 0xe5, 0x0e, 0xc8, 0x6d, + 0xb8, 0x76, 0x43, 0x96, 0x60, 0x75, 0x8a, 0x5d, 0x1b, 0x5e, 0x01, 0x49, 0xc7, 0x96, 0x53, 0x95, + 0xae, 0xcf, 0x0c, 0xfa, 0xe5, 0xe4, 0x66, 0x03, 0x25, 0x1d, 0x1b, 0x42, 0x30, 0xed, 0x62, 0x1d, + 0xc4, 0xd3, 0x48, 0x3e, 0xc3, 0x57, 0xc0, 0x54, 0x97, 0xb6, 0xe5, 0xd0, 0xd3, 0xf5, 0xd9, 0x41, + 0xbf, 0x3c, 0xf5, 0x04, 0x6d, 0x21, 0x21, 0x83, 0x0b, 0xe0, 0x52, 0xdb, 0x6b, 0x79, 0xcc, 0x9c, + 0x5e, 0x9a, 0xaa, 0xa4, 0x91, 0x7a, 0x59, 0xb6, 0x63, 0x9f, 0x7b, 0xe0, 0xd9, 0xa4, 0x2d, 0x12, + 0xca, 0xae, 0xf8, 0xae, 0x15, 0x7e, 0x54, 0x26, 0x14, 0xe9, 0xcb, 0x66, 0x03, 0xcd, 0x4a, 0xe5, + 0x66, 0xe0, 0x56, 0xf2, 0x54, 0xb7, 0xa6, 0x22, 0xb7, 0x96, 0xff, 0x25, 0x09, 0x5e, 0x0d, 0x3f, + 0xf3, 0x94, 0x50, 0x91, 0xd1, 0x37, 0xa3, 0x7a, 0x08, 0x3e, 0x1c, 0xfb, 0xe6, 0x9d, 0xd8, 0x37, + 0x07, 0x2f, 0xca, 0x6f, 0x80, 0xd7, 0x3f, 0xfe, 0x29, 0x5e, 0xf9, 0xbb, 0x9b, 0x2b, 0xdf, 0x7f, + 0x5e, 0xb9, 0x77, 0xf7, 0xa7, 0x2b, 0xcf, 0xef, 0x05, 0xaf, 0x6f, 0xfd, 0xfd, 0xda, 0x3b, 0xff, + 0x78, 0xe3, 0x1f, 0x3e, 0xbe, 0xd1, 0x7b, 0x23, 0x72, 0xee, 0x21, 0x48, 0x75, 0xc4, 0x68, 0xac, + 0xd0, 0x45, 0x49, 0x28, 0x47, 0x78, 0x21, 0x42, 0xc9, 0xb2, 0x69, 0x8b, 0xdd, 0xbb, 0x8f, 0xa9, + 0x7d, 0x84, 0x29, 0xb1, 0x0e, 0xd5, 0x00, 0xf4, 0x08, 0xf3, 0x81, 0x5c, 0x8f, 0x4b, 0x40, 0xf7, + 0x1c, 0xda, 0x19, 0x82, 0x4e, 0x2b, 0x68, 0x20, 0xd7, 0xd0, 0xe5, 0x7f, 0x9e, 0x05, 0x85, 0xd1, + 0x79, 0x81, 0xef, 0x83, 0x29, 0xc7, 0x66, 0x72, 0x1e, 0x32, 0x6b, 0xdf, 0x1e, 0xdd, 0x70, 0x67, + 0x4c, 0x63, 0xac, 0x3e, 0x12, 0x0c, 0xf0, 0x19, 0xc8, 0x6b, 0xc3, 0xd0, 0x8f, 0xa4, 0xdc, 0xc5, + 0x8b, 0x13, 0x62, 0x8f, 0xa6, 0xab, 0xc3, 0x41, 0xbf, 0x9c, 0xdb, 0xf2, 0x10, 0x7e, 0x56, 0xdb, + 0xd6, 0x32, 0x94, 0xd3, 0xd0, 0xc0, 0x43, 0x0c, 0xe6, 0x03, 0x62, 0x7f, 0xff, 0x78, 0x68, 0x3e, + 0x26, 0x90, 0xef, 0x7c, 0xf0, 0x51, 0x40, 0x7e, 0x79, 0xd0, 0x2f, 0x17, 0x35, 0x79, 0x24, 0x46, + 0x45, 0x8d, 0xde, 0xd9, 0x3f, 0x0e, 0x3e, 0x71, 0x0f, 0x14, 0xc3, 0x93, 0x6f, 0xf9, 0x6d, 0xec, + 0x8a, 0x95, 0x94, 0xb3, 0xa8, 0xb2, 0x7d, 0x78, 0xfa, 0x77, 0xda, 0xd8, 0xdd, 0x6c, 0xa0, 0xfc, + 0xde, 0x90, 0x40, 0x6c, 0xcf, 0x19, 0x7f, 0xdf, 0xe3, 0x1e, 0x33, 0x2f, 0xc9, 0xfd, 0xae, 0xdf, + 0x60, 0x05, 0x14, 0x58, 0xd7, 0xf7, 0x3d, 0xca, 0x99, 0xd5, 0x6c, 0x63, 0xc6, 0xac, 0x5d, 0x59, + 0x09, 0xa4, 0x50, 0x2e, 0x90, 0xaf, 0x0b, 0x71, 0x7d, 0x02, 0xb2, 0x29, 0x0b, 0x80, 0x51, 0xe4, + 0x3a, 0xec, 0x80, 0x2b, 0x36, 0xd9, 0xc3, 0xdd, 0x36, 0xb7, 0x3a, 0xb8, 0x69, 0xf9, 0x61, 0x18, + 0xd7, 0xc5, 0xde, 0x6b, 0x67, 0xc6, 0xfa, 0xba, 0x39, 0xe8, 0x97, 0x17, 0x1a, 0x8a, 0x60, 0x48, + 0x83, 0x16, 0x34, 0xed, 0x03, 0xdc, 0x8c, 0x95, 0x7c, 0xd7, 0xc1, 0x9c, 0x88, 0x77, 0x51, 0x64, + 0x4c, 0xab, 0xbc, 0xdb, 0x71, 0xa2, 0xd0, 0x2b, 0x41, 0xb8, 0x17, 0x03, 0x01, 0x0d, 0xc2, 0xbd, + 0x08, 0xb4, 0x04, 0xb2, 0x94, 0x30, 0xc2, 0x99, 0x2a, 0x63, 0x65, 0x21, 0x90, 0x42, 0x40, 0xc9, + 0x44, 0xfd, 0x0a, 0x7f, 0x00, 0x8a, 0x5d, 0x46, 0x98, 0x75, 0x7b, 0xcd, 0xda, 0x75, 0x74, 0xa5, + 0x2d, 0xf3, 0x7c, 0xaa, 0x5e, 0x1c, 0xf4, 0xcb, 0x73, 0x4f, 0x18, 0x61, 0xb7, 0xd7, 0xea, 0x8e, + 0xac, 0xb7, 0xd1, 0x5c, 0x37, 0xfe, 0x2a, 0x7c, 0x08, 0x67, 0x50, 0x64, 0x58, 0x99, 0xf1, 0x53, + 0x28, 0x1b, 0x08, 0x3f, 0xf4, 0x1c, 0x17, 0xbe, 0x03, 0xa0, 0xf6, 0x41, 0x66, 0x72, 0xd7, 0x73, + 0x9b, 0x84, 0xc9, 0xf4, 0x9d, 0x42, 0x05, 0xa5, 0x11, 0xb8, 0x6d, 0x29, 0x87, 0xcf, 0x01, 0x0c, + 0xa6, 0x7a, 0xcf, 0xa3, 0x1d, 0xcc, 0xe5, 0x34, 0xe7, 0xe5, 0x34, 0x57, 0xc6, 0xa6, 0x59, 0x35, + 0x3c, 0x3b, 0xf8, 0xb8, 0xed, 0x61, 0xfb, 0x7e, 0x88, 0xaf, 0x4f, 0x8b, 0x83, 0x82, 0x8a, 0x9a, + 0x29, 0x52, 0xe8, 0x18, 0xfc, 0xdf, 0x33, 0x20, 0xf3, 0xa0, 0xb6, 0xfe, 0x88, 0x70, 0x2e, 0x7a, + 0x1a, 0x78, 0x0f, 0xcc, 0x76, 0x19, 0xb1, 0xb0, 0x4d, 0xf5, 0xa9, 0x1c, 0xaf, 0xde, 0xeb, 0x9e, + 0xd7, 0x7e, 0x8a, 0xdb, 0x5d, 0x52, 0x07, 0x83, 0x7e, 0x79, 0xe6, 0x09, 0x23, 0xb5, 0x06, 0x42, + 0x33, 0x5d, 0x46, 0x6a, 0x36, 0x85, 0x9b, 0x40, 0x94, 0x95, 0x56, 0x07, 0xd3, 0x96, 0xa3, 0x0e, + 0xa1, 0xe8, 0x74, 0x46, 0x39, 0xee, 0xb7, 0x3d, 0xcc, 0x15, 0xc9, 0xdc, 0xa0, 0x5f, 0x4e, 0xd7, + 0x1a, 0xe8, 0x81, 0xb4, 0x40, 0x69, 0x6c, 0x53, 0xf5, 0x08, 0xdf, 0x07, 0x79, 0xbd, 0x6d, 0x65, + 0x41, 0xe5, 0x75, 0xb9, 0xee, 0x9c, 0x5e, 0x19, 0xe3, 0x6b, 0xe8, 0xa6, 0xb8, 0x3e, 0xfd, 0x1b, + 0xd1, 0x4c, 0xcc, 0x49, 0xbb, 0xfa, 0x63, 0x65, 0x15, 0x11, 0x35, 0x43, 0xa2, 0xe9, 0x8b, 0x10, + 0xad, 0x07, 0x44, 0xcf, 0xc0, 0x55, 0xc6, 0x31, 0xef, 0xb2, 0xf1, 0x0a, 0xef, 0xd2, 0xf9, 0x08, + 0x2f, 0x2b, 0xfb, 0xd1, 0xf2, 0xee, 0x29, 0x30, 0x35, 0xf1, 0x78, 0x79, 0x37, 0x23, 0x99, 0xaf, + 0x8d, 0x31, 0x3f, 0xd9, 0x74, 0xf9, 0xed, 0x35, 0x39, 0x89, 0xe8, 0x8a, 0xb2, 0x1e, 0xab, 0xeb, + 0x36, 0xe2, 0xc5, 0xf6, 0xec, 0x29, 0x5b, 0x27, 0x5a, 0xfe, 0xa0, 0xf0, 0x56, 0xa4, 0x51, 0xf5, + 0xfd, 0x7c, 0x72, 0x31, 0xad, 0x8e, 0x7c, 0xf5, 0x2c, 0xc2, 0xa1, 0x12, 0x41, 0xd1, 0x8e, 0x57, + 0xd7, 0xb5, 0xd1, 0xea, 0x3a, 0x7d, 0xc6, 0x90, 0xbf, 0x73, 0x47, 0xd1, 0x0c, 0xd5, 0xde, 0x8b, + 0x3f, 0x02, 0xd9, 0xb8, 0xef, 0x70, 0x05, 0x5c, 0x3a, 0x14, 0x0f, 0x72, 0x17, 0x9f, 0xd1, 0x61, + 0x28, 0xd4, 0xe2, 0x26, 0x80, 0xe3, 0x9e, 0xc2, 0xdb, 0xc3, 0x24, 0x5f, 0x52, 0x11, 0x29, 0xec, + 0xf2, 0x7f, 0xa4, 0x41, 0x4a, 0xcc, 0x00, 0xc7, 0x9c, 0x40, 0x04, 0x60, 0xb3, 0x4b, 0x29, 0x11, + 0x4b, 0x1a, 0x85, 0x4a, 0xe3, 0x3c, 0xa1, 0x52, 0x1f, 0x5c, 0x6d, 0x1e, 0x8b, 0x89, 0x48, 0xc4, + 0x05, 0xe6, 0x50, 0x62, 0xc7, 0x39, 0x93, 0x17, 0xe0, 0xd4, 0xe6, 0x31, 0xce, 0xef, 0x81, 0xac, + 0xba, 0x0a, 0x53, 0xe1, 0x5f, 0xe7, 0xb7, 0xcb, 0xa3, 0x6c, 0x32, 0x09, 0xa0, 0x8c, 0x82, 0xca, + 0x97, 0x49, 0x99, 0x77, 0xfa, 0xff, 0x24, 0xf3, 0x3e, 0x07, 0x8b, 0xe1, 0xd5, 0x83, 0x43, 0x3b, + 0xc4, 0xb6, 0xc2, 0x42, 0x19, 0x73, 0x7d, 0xdc, 0xce, 0xba, 0x5a, 0x98, 0x96, 0xd7, 0x0a, 0x57, + 0x83, 0x2b, 0x0a, 0x49, 0xd1, 0xd0, 0x0c, 0x35, 0x0e, 0xdf, 0x05, 0xa6, 0xa4, 0xb7, 0xc9, 0xa1, + 0xa5, 0x8f, 0x5e, 0x78, 0xb7, 0xa2, 0xae, 0x42, 0xe6, 0x85, 0xbe, 0x41, 0x0e, 0x1f, 0x49, 0xad, + 0xbe, 0x64, 0x41, 0xe0, 0x72, 0xd4, 0x6a, 0xc4, 0x4f, 0xe9, 0xac, 0x1c, 0x74, 0x69, 0xac, 0x22, + 0xd0, 0x7d, 0x85, 0x3a, 0x94, 0x68, 0xde, 0x1f, 0x7a, 0x57, 0x87, 0x94, 0x80, 0x6b, 0x3e, 0x71, + 0x6d, 0x41, 0x8b, 0x7d, 0xbf, 0xed, 0x34, 0x65, 0xc0, 0x08, 0x87, 0xab, 0x8f, 0xd9, 0x78, 0x2b, + 0x16, 0x61, 0x83, 0x71, 0xa1, 0x45, 0x4d, 0x34, 0x41, 0x07, 0x37, 0x40, 0xe1, 0xe7, 0x5d, 0xd2, + 0x25, 0xb6, 0x45, 0x09, 0xf3, 0x3d, 0x97, 0x11, 0x66, 0xa6, 0x65, 0x83, 0x36, 0x69, 0xa9, 0xd6, + 0xbd, 0x4e, 0x07, 0xbb, 0x36, 0xca, 0x2b, 0x1b, 0x14, 0x98, 0x08, 0x9a, 0xc0, 0x5b, 0x79, 0xfa, + 0x18, 0x67, 0x26, 0xf8, 0x72, 0x1a, 0x6d, 0x83, 0xb4, 0x09, 0xfc, 0x1b, 0x00, 0xb5, 0x37, 0x32, + 0x17, 0xe2, 0x66, 0x93, 0xf8, 0x2a, 0x2b, 0x4f, 0x18, 0x6a, 0x70, 0x9e, 0xaa, 0x22, 0x3d, 0xd6, + 0x24, 0x14, 0xe9, 0xc1, 0x44, 0x12, 0xf8, 0x00, 0x2c, 0x04, 0x9e, 0x49, 0x4e, 0xed, 0x9e, 0xcc, + 0xe1, 0x13, 0xae, 0xdb, 0x84, 0xa5, 0x76, 0x07, 0x41, 0x6d, 0x18, 0x93, 0xc1, 0x9b, 0x60, 0x81, + 0xf6, 0xac, 0x23, 0xc7, 0xb5, 0xbd, 0x23, 0x66, 0xe1, 0x43, 0xec, 0xb4, 0x45, 0x23, 0xa3, 0x33, + 0x3b, 0xa4, 0xbd, 0x67, 0x4a, 0x55, 0x0b, 0x34, 0x8b, 0xff, 0x6e, 0x00, 0x10, 0xf3, 0x67, 0x19, + 0xcc, 0xfa, 0x2a, 0x1f, 0xcb, 0x13, 0x9f, 0xad, 0xa7, 0x06, 0x2f, 0xca, 0xd3, 0x7e, 0xa6, 0xf7, + 0x1a, 0x0a, 0x14, 0xf0, 0x07, 0x60, 0x36, 0x70, 0x33, 0xf9, 0xa5, 0x6e, 0xea, 0xf3, 0x1b, 0x58, + 0xc0, 0x77, 0xcf, 0x7f, 0x9f, 0xa8, 0x2c, 0x25, 0x5c, 0x67, 0xfe, 0x7f, 0x32, 0x41, 0x3a, 0xac, + 0xb0, 0xe1, 0x7b, 0xf1, 0x4a, 0xfc, 0xc6, 0xa9, 0x95, 0xf8, 0x19, 0x25, 0xf8, 0x3a, 0x00, 0x4d, + 0x4a, 0xb0, 0xbe, 0xfa, 0x4b, 0x5e, 0xe4, 0xea, 0x4f, 0xdb, 0xd5, 0xb8, 0x20, 0xe9, 0xfa, 0x76, + 0x40, 0x32, 0x75, 0x11, 0x12, 0x6d, 0x57, 0xe3, 0x61, 0x5b, 0x36, 0x1d, 0xeb, 0x16, 0x97, 0x40, + 0xc6, 0x26, 0xac, 0x49, 0x1d, 0x5f, 0x9c, 0x09, 0x19, 0x3e, 0xd2, 0x28, 0x2e, 0x92, 0x85, 0x0b, + 0xe7, 0xd4, 0xd9, 0xed, 0x72, 0xc2, 0xcc, 0x19, 0xb9, 0xa3, 0xdf, 0x3a, 0x75, 0x22, 0xaa, 0xb5, + 0x10, 0xbb, 0xe1, 0x72, 0x7a, 0x8c, 0x62, 0xc6, 0xf0, 0x67, 0x20, 0xa3, 0x63, 0xa1, 0x25, 0x26, + 0x75, 0xf6, 0xe2, 0xed, 0x8d, 0xbc, 0xaa, 0x0b, 0xe4, 0x0d, 0x86, 0xc0, 0x61, 0x80, 0x61, 0xb0, + 0x0e, 0x20, 0x23, 0x54, 0x06, 0x6b, 0x9f, 0x7a, 0x7b, 0x4e, 0x9b, 0x88, 0x86, 0x21, 0x25, 0x1b, + 0x06, 0x79, 0xc5, 0xf8, 0x48, 0x69, 0x77, 0x94, 0x72, 0xb3, 0x81, 0x0a, 0x6c, 0x58, 0x62, 0xc3, + 0x3b, 0xe0, 0x8a, 0xbe, 0xbd, 0xb6, 0x84, 0x8e, 0x50, 0x79, 0xdb, 0x4d, 0x18, 0x93, 0xa9, 0x37, + 0x8d, 0x16, 0xb4, 0xf6, 0x91, 0x54, 0xd6, 0x94, 0x0e, 0xfe, 0x10, 0x2c, 0xc6, 0x03, 0xd4, 0x88, + 0x25, 0x90, 0x96, 0x66, 0x0c, 0x31, 0x6c, 0x5d, 0x05, 0xf3, 0xf2, 0x58, 0x8e, 0x98, 0x65, 0xa4, + 0x59, 0x51, 0xa8, 0x86, 0xf1, 0xf7, 0x41, 0xba, 0xed, 0x29, 0x22, 0x66, 0x66, 0xe5, 0x7a, 0x54, + 0x4e, 0x5f, 0x8f, 0xad, 0x00, 0xaa, 0x96, 0x23, 0x32, 0x9d, 0xd8, 0x06, 0xcd, 0x9d, 0xbb, 0x0d, + 0xca, 0x4d, 0x6c, 0x83, 0x26, 0x64, 0xbd, 0xfc, 0x37, 0xd9, 0x6f, 0x16, 0xbe, 0xe9, 0x7e, 0xb3, + 0x78, 0x81, 0x7e, 0xf3, 0xf4, 0x1e, 0x10, 0xfe, 0xbf, 0xf4, 0x80, 0xf3, 0xe7, 0xe9, 0x01, 0x17, + 0xce, 0xd1, 0x03, 0x5e, 0x3e, 0x5f, 0x0f, 0x78, 0xe5, 0xab, 0xf6, 0x80, 0x57, 0xcf, 0xdd, 0x03, + 0x9a, 0xa7, 0xf4, 0x80, 0xef, 0x82, 0x34, 0xf5, 0x3c, 0x6e, 0xc9, 0x30, 0xff, 0x8a, 0x9c, 0x5d, + 0x73, 0xac, 0x94, 0xf5, 0x3c, 0x2e, 0x62, 0x3c, 0x4a, 0x51, 0xfd, 0x04, 0x9f, 0x82, 0x19, 0x97, + 0x70, 0xb1, 0xae, 0x8b, 0x32, 0xf1, 0xdc, 0xfb, 0x53, 0xbf, 0xbc, 0x76, 0xa1, 0xdf, 0xae, 0xb6, + 0x09, 0xdf, 0x6c, 0x0c, 0xfa, 0xe5, 0x4b, 0xf2, 0x01, 0x5d, 0x72, 0x09, 0x97, 0x77, 0x4d, 0x59, + 0xb1, 0xe2, 0x4c, 0x57, 0xf7, 0xe6, 0xab, 0x93, 0x13, 0x4f, 0xac, 0x01, 0x50, 0x3f, 0x06, 0xc4, + 0x04, 0x28, 0xd3, 0xc1, 0xcd, 0xb0, 0xdd, 0x5c, 0x07, 0x69, 0x49, 0x28, 0x92, 0xbb, 0x79, 0x6d, + 0xf2, 0xf8, 0x82, 0xe4, 0x5f, 0xcf, 0x0e, 0xfa, 0xe5, 0xb0, 0xb4, 0x46, 0x29, 0xc1, 0x23, 0x8b, + 0xec, 0x5b, 0x60, 0x96, 0xa9, 0x54, 0x67, 0xbe, 0x26, 0x29, 0xae, 0x9e, 0x92, 0x09, 0x51, 0x80, + 0x83, 0xef, 0x81, 0xa0, 0x20, 0xb1, 0x02, 0xd3, 0xd2, 0xd9, 0xa6, 0x39, 0x8d, 0x0f, 0x7e, 0x24, + 0xbc, 0x01, 0x72, 0x61, 0xfd, 0x28, 0x17, 0xd1, 0x2c, 0xcb, 0xaa, 0x31, 0xab, 0xab, 0x46, 0xb9, + 0x80, 0xf0, 0x4d, 0x90, 0xef, 0x32, 0x62, 0x47, 0x28, 0x66, 0x2e, 0x2d, 0x4d, 0x55, 0xe6, 0xe4, + 0xd6, 0xb1, 0x03, 0x18, 0x13, 0x38, 0xc9, 0x16, 0xed, 0x09, 0xf3, 0xf5, 0xe8, 0xf7, 0xb8, 0x70, + 0x43, 0xc0, 0xef, 0x6a, 0x1c, 0xfd, 0x44, 0x37, 0x8a, 0x37, 0xcd, 0x65, 0xf9, 0x9b, 0x4b, 0x61, + 0xd0, 0x2f, 0x67, 0xb7, 0x30, 0xe3, 0xe8, 0x43, 0xd9, 0x04, 0xde, 0x54, 0x8e, 0xa0, 0x4f, 0xd4, + 0xdb, 0xb8, 0xe1, 0x2d, 0xf3, 0xfa, 0x44, 0xc3, 0x5b, 0x43, 0x86, 0xb7, 0xe0, 0xc7, 0xe0, 0xd5, + 0xd1, 0x3a, 0x99, 0x92, 0x26, 0x71, 0x0e, 0x55, 0x8a, 0xbe, 0x71, 0x91, 0x3a, 0x3c, 0x2c, 0xa6, + 0x91, 0x66, 0xa8, 0x89, 0x13, 0x97, 0x51, 0xbf, 0x72, 0xa9, 0x3d, 0xf0, 0xc6, 0x29, 0x81, 0x4e, + 0x40, 0xd4, 0xba, 0x03, 0x3f, 0x7c, 0x86, 0x2b, 0x00, 0xee, 0xca, 0xeb, 0x8c, 0x63, 0x51, 0x8b, + 0x37, 0x89, 0xcb, 0x71, 0x8b, 0x98, 0x6f, 0x2e, 0x19, 0x95, 0x24, 0x2a, 0x6a, 0xcd, 0x4e, 0xa8, + 0x80, 0xdf, 0x02, 0xf9, 0xb0, 0x87, 0xd0, 0x17, 0x14, 0xdf, 0x5a, 0x32, 0x2a, 0x97, 0x50, 0x2e, + 0x10, 0xeb, 0x9b, 0x07, 0x2c, 0x0e, 0xa9, 0xb0, 0xb2, 0xb0, 0x4d, 0xf5, 0x75, 0x36, 0x33, 0x2b, + 0x32, 0x07, 0x8d, 0x45, 0x37, 0x75, 0xb3, 0xad, 0x2f, 0x60, 0x54, 0x06, 0x46, 0xd2, 0xb8, 0xd6, + 0x40, 0x4a, 0xc7, 0xc4, 0xc9, 0x96, 0x12, 0x9b, 0x6a, 0x09, 0x6c, 0x80, 0x9c, 0xfe, 0x44, 0x40, + 0xff, 0xd6, 0x39, 0xe8, 0xd1, 0x9c, 0x32, 0x0a, 0x58, 0x3e, 0x04, 0x9a, 0x39, 0xec, 0x16, 0x98, + 0xf9, 0xb6, 0xe4, 0x29, 0x8f, 0x35, 0xab, 0xc1, 0x10, 0x35, 0x53, 0x5e, 0x19, 0x06, 0x62, 0x26, + 0xda, 0x10, 0x5d, 0x91, 0x4f, 0xea, 0x42, 0x98, 0xf9, 0x6d, 0xc9, 0x7b, 0xbe, 0x36, 0x44, 0x11, + 0x4d, 0x50, 0x31, 0xf8, 0x01, 0x00, 0xb1, 0xeb, 0xac, 0x77, 0x2e, 0x76, 0x9d, 0x85, 0x62, 0xb6, + 0x10, 0x83, 0x9c, 0x4f, 0xbd, 0x43, 0x47, 0x9c, 0x47, 0x42, 0x45, 0xb4, 0x5b, 0x91, 0x59, 0xec, + 0xae, 0x88, 0xd4, 0x3b, 0x91, 0xe6, 0x22, 0xb7, 0xe0, 0x73, 0x31, 0xc6, 0x4d, 0x1b, 0x36, 0x40, + 0x31, 0x14, 0x88, 0x60, 0x61, 0x63, 0x8e, 0xcd, 0xaa, 0x8e, 0x14, 0xa3, 0x7b, 0xfe, 0x91, 0xfc, + 0xbf, 0x0a, 0x54, 0x88, 0x5b, 0x34, 0x30, 0xc7, 0x8b, 0x3f, 0x02, 0xf9, 0x91, 0x72, 0x11, 0x16, + 0xc0, 0xd4, 0x01, 0x51, 0xbf, 0x0a, 0xa5, 0x91, 0x78, 0x84, 0x0b, 0xc1, 0x65, 0x83, 0xfa, 0x91, + 0x43, 0xbd, 0xdc, 0x4d, 0x7e, 0xcf, 0x58, 0x7c, 0x0a, 0x72, 0xc3, 0xd5, 0xcd, 0x04, 0xeb, 0x6a, + 0xdc, 0x7a, 0x42, 0x10, 0x0d, 0x08, 0x62, 0xbc, 0xba, 0x0f, 0xf8, 0x00, 0x80, 0xb0, 0x8a, 0x62, + 0xf0, 0x2e, 0xc8, 0x44, 0xff, 0x17, 0x23, 0xfa, 0x81, 0x29, 0x79, 0xab, 0x75, 0x5a, 0xd9, 0x85, + 0x00, 0x09, 0x6d, 0x97, 0x7f, 0x06, 0xae, 0xac, 0xcb, 0x4a, 0x3e, 0x52, 0xeb, 0x46, 0xa5, 0x0e, + 0x40, 0xc4, 0xaa, 0x9b, 0x8c, 0xd3, 0x49, 0x63, 0x9d, 0x45, 0x3a, 0xa4, 0x5f, 0xfe, 0x57, 0x03, + 0x5c, 0x79, 0x22, 0x6b, 0xfc, 0x6f, 0x82, 0x1e, 0xde, 0x03, 0x20, 0xfa, 0xcf, 0x99, 0x53, 0xdb, + 0x97, 0xfb, 0x02, 0xf2, 0x00, 0xb3, 0x03, 0xdd, 0x50, 0xa5, 0xf7, 0x02, 0xc1, 0xf2, 0x7f, 0x19, + 0x60, 0xfe, 0x7d, 0xc2, 0xc7, 0x9c, 0x7b, 0x0c, 0x72, 0x91, 0x73, 0xd6, 0x57, 0x6f, 0xb2, 0xb2, + 0x24, 0xd2, 0xb3, 0xaf, 0xef, 0xee, 0xff, 0x18, 0xe0, 0xf2, 0x96, 0xc3, 0x22, 0x7f, 0x59, 0xe0, + 0xf0, 0x47, 0x20, 0x1f, 0x0f, 0x00, 0x91, 0xc7, 0x6f, 0x9e, 0x71, 0xf4, 0x27, 0xfb, 0x9c, 0xc3, + 0x71, 0xc4, 0xd7, 0xf7, 0x5a, 0x1c, 0x12, 0x8f, 0xda, 0x84, 0xea, 0x1f, 0xa4, 0xd4, 0x8b, 0xfc, + 0xbd, 0x4f, 0xfe, 0xd3, 0x82, 0xfa, 0xa7, 0x18, 0xf5, 0x22, 0xda, 0x40, 0x5f, 0xa4, 0x03, 0xf5, + 0x2f, 0x30, 0xf2, 0x79, 0xf9, 0x57, 0x06, 0x98, 0x7f, 0x34, 0x61, 0x91, 0xbe, 0x0b, 0x66, 0xce, + 0xbb, 0x7b, 0x94, 0x4f, 0x1a, 0xfe, 0xb5, 0x47, 0xf4, 0xf6, 0x7d, 0x00, 0xa2, 0xe4, 0x06, 0x8b, + 0x60, 0x6e, 0xe7, 0xe1, 0xb3, 0x0d, 0x64, 0x3d, 0xd9, 0xfe, 0xf1, 0xf6, 0xc3, 0x67, 0xdb, 0x85, + 0x44, 0x24, 0xaa, 0xd7, 0x1e, 0x3f, 0xde, 0x40, 0x1f, 0x15, 0x0c, 0x08, 0x41, 0x4e, 0x89, 0x36, + 0xfe, 0xf6, 0xf1, 0x06, 0xda, 0xae, 0x6d, 0x15, 0x92, 0xf5, 0x7f, 0x33, 0x3e, 0x7b, 0x59, 0x32, + 0x3e, 0x7f, 0x59, 0x32, 0xfe, 0xf8, 0xb2, 0x94, 0xf8, 0xf3, 0xcb, 0x52, 0xe2, 0x2f, 0x2f, 0x4b, + 0x89, 0xbf, 0xbe, 0x2c, 0x25, 0xbe, 0x78, 0x59, 0x32, 0x7e, 0x31, 0x28, 0x19, 0xbf, 0x1c, 0x94, + 0x12, 0xbf, 0x1b, 0x94, 0x8c, 0xdf, 0x0f, 0x4a, 0x89, 0x4f, 0x07, 0xa5, 0xc4, 0x1f, 0x06, 0xa5, + 0xc4, 0x67, 0x83, 0x92, 0xf1, 0xf9, 0xa0, 0x64, 0xfc, 0x71, 0x50, 0x4a, 0xfc, 0x79, 0x50, 0x32, + 0xfe, 0x32, 0x28, 0x25, 0xfe, 0x3a, 0x28, 0x19, 0x5f, 0x0c, 0x4a, 0x89, 0x5f, 0x9c, 0x94, 0x12, + 0xbf, 0x3c, 0x29, 0x19, 0xbf, 0x3e, 0x29, 0x25, 0x7e, 0x73, 0x52, 0x32, 0x7e, 0x7b, 0x52, 0x4a, + 0xfc, 0xee, 0xa4, 0x94, 0xf8, 0xfd, 0x49, 0xc9, 0xf8, 0xf4, 0xa4, 0x64, 0xfc, 0xe1, 0xa4, 0x64, + 0xfc, 0xe4, 0x9d, 0xf3, 0x56, 0x95, 0xdc, 0xf5, 0x77, 0x77, 0x67, 0xe4, 0x8c, 0xdc, 0xfe, 0xdf, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xd3, 0xf1, 0xbd, 0x62, 0x8e, 0x27, 0x00, 0x00, } From 8b5a289fe07cf5597d7cc70616dbbf68e03f4201 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 12 Feb 2019 19:16:34 +0100 Subject: [PATCH 08/40] cli: Add default NS MAC settings to shared config --- cmd/internal/shared/networkserver/config.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cmd/internal/shared/networkserver/config.go b/cmd/internal/shared/networkserver/config.go index 913fc1a923..9fef046d40 100644 --- a/cmd/internal/shared/networkserver/config.go +++ b/cmd/internal/shared/networkserver/config.go @@ -17,9 +17,15 @@ package networkserver import ( "time" + pbtypes "github.com/gogo/protobuf/types" "go.thethings.network/lorawan-stack/pkg/networkserver" + "go.thethings.network/lorawan-stack/pkg/ttnpb" ) +func durationPtr(v time.Duration) *time.Duration { + return &v +} + // DefaultNetworkServerConfig is the default configuration for the NetworkServer var DefaultNetworkServerConfig = networkserver.Config{ DeduplicationWindow: 200 * time.Millisecond, @@ -29,4 +35,13 @@ var DefaultNetworkServerConfig = networkserver.Config{ MACCommands: "highest", MaxApplicationDownlink: "high", }, + DefaultMACSettings: ttnpb.MACSettings{ + UseADR: &pbtypes.BoolValue{Value: true}, + ADRMargin: &pbtypes.FloatValue{Value: networkserver.DefaultADRMargin}, + ClassBTimeout: durationPtr(time.Minute), + ClassCTimeout: durationPtr(networkserver.DefaultClassCTimeout), + StatusTimePeriodicity: durationPtr(networkserver.DefaultStatusTimePeriodicity), + StatusCountPeriodicity: &pbtypes.UInt32Value{Value: networkserver.DefaultStatusCountPeriodicity}, + Rx1Delay: &ttnpb.MACSettings_RxDelayValue{Value: ttnpb.RX_DELAY_5}, + }, } From 0fb94473b0e227d7de7982f96d637abcc3af5d9d Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 12 Feb 2019 19:35:38 +0100 Subject: [PATCH 09/40] util: Add NetID support to config --- pkg/config/config.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 3c324c73ba..f22dbc94c8 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -27,6 +27,7 @@ import ( "github.com/mitchellh/mapstructure" "github.com/spf13/pflag" "github.com/spf13/viper" + "go.thethings.network/lorawan-stack/pkg/types" ) // TimeFormat is the format to parse times in. @@ -308,7 +309,7 @@ func (m *Manager) setDefaults(prefix string, flags *pflag.FlagSet, config interf } if configKind != reflect.Struct { - return + panic("default config is not a struct type") } for i := 0; i < configValue.NumField(); i++ { @@ -468,12 +469,17 @@ func (m *Manager) setDefaults(prefix string, flags *pflag.FlagSet, config interf m.viper.SetDefault(name, val) case []byte: - var str string + str := fmt.Sprintf("0x%X", val) if len(val) > 0 { - m.viper.SetDefault(name, fmt.Sprintf("0x%X", val)) + m.viper.SetDefault(name, str) } flags.StringP(name, shorthand, str, description) + case types.NetID: + str := fmt.Sprintf("%X", val) + m.viper.SetDefault(name, str) + flags.StringP(name, shorthand, str, description) + default: switch fieldType { case reflect.Struct: From d34d7839a4115dac9e78a652495a5ea374abd2a2 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 12 Feb 2019 20:12:47 +0100 Subject: [PATCH 10/40] util: Add ttnpb.RxDelay support to config package --- pkg/config/config.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/config/config.go b/pkg/config/config.go index f22dbc94c8..ed0250e9c8 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -27,6 +27,7 @@ import ( "github.com/mitchellh/mapstructure" "github.com/spf13/pflag" "github.com/spf13/viper" + "go.thethings.network/lorawan-stack/pkg/ttnpb" "go.thethings.network/lorawan-stack/pkg/types" ) @@ -480,6 +481,10 @@ func (m *Manager) setDefaults(prefix string, flags *pflag.FlagSet, config interf m.viper.SetDefault(name, str) flags.StringP(name, shorthand, str, description) + case ttnpb.RxDelay: + m.viper.SetDefault(name, int32(val)) + flags.Int32P(name, shorthand, int32(val), description) + default: switch fieldType { case reflect.Struct: From e97bb2f884debd9b11eb873146721c2cf075b616 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 12 Feb 2019 20:13:07 +0100 Subject: [PATCH 11/40] util: Fix byte slice/array handling in config --- pkg/config/config.go | 4 +++- pkg/config/hooks.go | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index ed0250e9c8..e2d55fc83b 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -213,6 +213,7 @@ func (m *Manager) Unmarshal(result interface{}) error { configurableInterfaceHook, configurableInterfaceSliceHook, stringToByteSliceHook, + stringToByteArrayHook, ), }) if err != nil { @@ -470,8 +471,9 @@ func (m *Manager) setDefaults(prefix string, flags *pflag.FlagSet, config interf m.viper.SetDefault(name, val) case []byte: - str := fmt.Sprintf("0x%X", val) + var str string if len(val) > 0 { + str = fmt.Sprintf("0x%X", val) m.viper.SetDefault(name, str) } flags.StringP(name, shorthand, str, description) diff --git a/pkg/config/hooks.go b/pkg/config/hooks.go index a57012faa0..dde3e93fbb 100644 --- a/pkg/config/hooks.go +++ b/pkg/config/hooks.go @@ -212,3 +212,24 @@ func stringToByteSliceHook(f reflect.Type, t reflect.Type, data interface{}) (in return slice, nil } + +func stringToByteArrayHook(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { + if f.Kind() != reflect.String || t.Kind() != reflect.Array || t.Elem().Kind() != reflect.Uint8 { + return data, nil + } + + str := strings.TrimPrefix(data.(string), "0x") + slice, err := hex.DecodeString(str) + if err != nil { + return nil, fmt.Errorf("Could not decode hex: %s", err) + } + if len(slice) != t.Len() { + return nil, fmt.Errorf("Invalid length: expected %d, got %d", t.Len(), len(slice)) + } + + rv := reflect.New(t).Elem() + for i, v := range slice { + rv.Index(i).SetUint(uint64(v)) + } + return rv.Interface(), nil +} From 54792d5b3110d8e6c95edf44d1634f896de21382 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 12 Feb 2019 20:35:07 +0100 Subject: [PATCH 12/40] ns,cli: Duplicate overridable MAC settings in networkserver config --- cmd/internal/shared/networkserver/config.go | 20 ++++++-------------- pkg/networkserver/config.go | 19 ++++++++++++------- pkg/networkserver/downlink_internal_test.go | 6 ++---- pkg/networkserver/networkserver.go | 17 ++++++++++++++++- 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/cmd/internal/shared/networkserver/config.go b/cmd/internal/shared/networkserver/config.go index 9fef046d40..d025115134 100644 --- a/cmd/internal/shared/networkserver/config.go +++ b/cmd/internal/shared/networkserver/config.go @@ -17,15 +17,10 @@ package networkserver import ( "time" - pbtypes "github.com/gogo/protobuf/types" "go.thethings.network/lorawan-stack/pkg/networkserver" "go.thethings.network/lorawan-stack/pkg/ttnpb" ) -func durationPtr(v time.Duration) *time.Duration { - return &v -} - // DefaultNetworkServerConfig is the default configuration for the NetworkServer var DefaultNetworkServerConfig = networkserver.Config{ DeduplicationWindow: 200 * time.Millisecond, @@ -35,13 +30,10 @@ var DefaultNetworkServerConfig = networkserver.Config{ MACCommands: "highest", MaxApplicationDownlink: "high", }, - DefaultMACSettings: ttnpb.MACSettings{ - UseADR: &pbtypes.BoolValue{Value: true}, - ADRMargin: &pbtypes.FloatValue{Value: networkserver.DefaultADRMargin}, - ClassBTimeout: durationPtr(time.Minute), - ClassCTimeout: durationPtr(networkserver.DefaultClassCTimeout), - StatusTimePeriodicity: durationPtr(networkserver.DefaultStatusTimePeriodicity), - StatusCountPeriodicity: &pbtypes.UInt32Value{Value: networkserver.DefaultStatusCountPeriodicity}, - Rx1Delay: &ttnpb.MACSettings_RxDelayValue{Value: ttnpb.RX_DELAY_5}, - }, + DefaultADRMargin: func(v float32) *float32 { return &v }(networkserver.DefaultADRMargin), + DefaultRx1Delay: func(v ttnpb.RxDelay) *ttnpb.RxDelay { return &v }(ttnpb.RX_DELAY_5), + DefaultClassBTimeout: func(v time.Duration) *time.Duration { return &v }(time.Minute), + DefaultClassCTimeout: func(v time.Duration) *time.Duration { return &v }(networkserver.DefaultClassCTimeout), + DefaultStatusTimePeriodicity: func(v time.Duration) *time.Duration { return &v }(networkserver.DefaultStatusTimePeriodicity), + DefaultStatusCountPeriodicity: func(v uint32) *uint32 { return &v }(networkserver.DefaultStatusCountPeriodicity), } diff --git a/pkg/networkserver/config.go b/pkg/networkserver/config.go index 35bbcaf6c5..7ac9daee87 100644 --- a/pkg/networkserver/config.go +++ b/pkg/networkserver/config.go @@ -24,13 +24,18 @@ import ( // Config represents the NetworkServer configuration. type Config struct { - Devices DeviceRegistry `name:"-"` - DownlinkTasks DownlinkTaskQueue `name:"-"` - DeduplicationWindow time.Duration `name:"deduplication-window" description:"Time window during which, duplicate messages are collected for metadata"` - CooldownWindow time.Duration `name:"cooldown-window" description:"Time window starting right after deduplication window, during which, duplicate messages are discarded"` - DownlinkPriorities DownlinkPriorityConfig `name:"downlink-priorities" description:"Downlink message priorities"` - NetID types.NetID `name:"net_id" description:"NetID of this Network Server"` - DefaultMACSettings ttnpb.MACSettings `name:"mac_defaults" description:"Default MAC settings to use if not specified for device"` + Devices DeviceRegistry `name:"-"` + DownlinkTasks DownlinkTaskQueue `name:"-"` + DeduplicationWindow time.Duration `name:"deduplication-window" description:"Time window during which, duplicate messages are collected for metadata"` + CooldownWindow time.Duration `name:"cooldown-window" description:"Time window starting right after deduplication window, during which, duplicate messages are discarded"` + DownlinkPriorities DownlinkPriorityConfig `name:"downlink-priorities" description:"Downlink message priorities"` + NetID types.NetID `name:"net_id" description:"NetID of this Network Server"` + DefaultADRMargin *float32 `name:"default-adr-margin" description:"The default margin Network Server should add in ADR requests if not configured in device's MAC settings"` + DefaultRx1Delay *ttnpb.RxDelay `name:"default-rx1-delay" description:"Rx1Delay value Network Server should use if not configured in device's MAC settings"` + DefaultClassBTimeout *time.Duration `name:"default-class-b-timeout" description:"Deadline for a device in class B mode to respond to requests from the Network Server if not configured in device's MAC settings"` + DefaultClassCTimeout *time.Duration `name:"default-class-c-timeout" description:"Deadline for a device in class C mode to respond to requests from the Network Server if not configured in device's MAC settings"` + DefaultStatusTimePeriodicity *time.Duration `name:"default-status-time-periodicity" description:"The interval after which a DevStatusReq MACCommand shall be sent by Network Server if not configured in device's MAC settings"` + DefaultStatusCountPeriodicity *uint32 `name:"default-status-count-periodicity" description:"Number of uplink messages after which a DevStatusReq MACCommand shall be sent by Network Server if not configured in device's MAC settings"` } // DownlinkPriorityConfig defines priorities for downlink messages. diff --git a/pkg/networkserver/downlink_internal_test.go b/pkg/networkserver/downlink_internal_test.go index a48461361e..017a5bff55 100644 --- a/pkg/networkserver/downlink_internal_test.go +++ b/pkg/networkserver/downlink_internal_test.go @@ -2548,10 +2548,8 @@ func TestProcessDownlinkTask(t *testing.T) { Devices: &MockDeviceRegistry{ SetByIDFunc: tc.SetByIDFunc, }, - DefaultMACSettings: ttnpb.MACSettings{ - StatusTimePeriodicity: DurationPtr(0), - StatusCountPeriodicity: &pbtypes.UInt32Value{Value: 0}, - }, + DefaultStatusTimePeriodicity: DurationPtr(0), + DefaultStatusCountPeriodicity: func(v uint32) *uint32 { return &v }(0), }, )).(*NetworkServer) ns.FrequencyPlans = frequencyplans.NewStore(test.FrequencyPlansFetcher) diff --git a/pkg/networkserver/networkserver.go b/pkg/networkserver/networkserver.go index 5eae3a68be..ddf422766d 100644 --- a/pkg/networkserver/networkserver.go +++ b/pkg/networkserver/networkserver.go @@ -22,6 +22,7 @@ import ( "sync" "time" + pbtypes "github.com/gogo/protobuf/types" "github.com/grpc-ecosystem/grpc-gateway/runtime" "go.thethings.network/lorawan-stack/pkg/cluster" "go.thethings.network/lorawan-stack/pkg/component" @@ -208,7 +209,11 @@ func New(c *component.Component, conf *Config, opts ...Option) (*NetworkServer, macHandlers: &sync.Map{}, downlinkTasks: conf.DownlinkTasks, downlinkPriorities: downlinkPriorities, - defaultMACSettings: conf.DefaultMACSettings, + defaultMACSettings: ttnpb.MACSettings{ + ClassBTimeout: conf.DefaultClassBTimeout, + ClassCTimeout: conf.DefaultClassCTimeout, + StatusTimePeriodicity: conf.DefaultStatusTimePeriodicity, + }, } ns.hashPool.New = func() interface{} { return fnv.New64a() @@ -217,6 +222,16 @@ func New(c *component.Component, conf *Config, opts ...Option) (*NetworkServer, return &metadataAccumulator{} } + if conf.DefaultADRMargin != nil { + ns.defaultMACSettings.ADRMargin = &pbtypes.FloatValue{Value: *conf.DefaultADRMargin} + } + if conf.DefaultRx1Delay != nil { + ns.defaultMACSettings.Rx1Delay = &ttnpb.MACSettings_RxDelayValue{Value: *conf.DefaultRx1Delay} + } + if conf.DefaultStatusCountPeriodicity != nil { + ns.defaultMACSettings.StatusCountPeriodicity = &pbtypes.UInt32Value{Value: *conf.DefaultStatusCountPeriodicity} + } + for _, opt := range opts { opt(ns) } From fa0f0e7ee855c3466148a5bbf4f17a2ba2c4e97e Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 12 Feb 2019 20:39:35 +0100 Subject: [PATCH 13/40] util: Fix numeric pointer field handling in config --- pkg/config/config.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index e2d55fc83b..56eef434c2 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -409,17 +409,17 @@ func (m *Manager) setDefaults(prefix string, flags *pflag.FlagSet, config interf flags.BoolP(name, shorthand, val, description) case int, int8, int16, int32, int64: - fieldValue := configValue.Field(i).Int() + fieldValue := reflect.Indirect(configValue.Field(i)).Int() m.viper.SetDefault(name, int(fieldValue)) flags.IntP(name, shorthand, int(fieldValue), description) case uint, uint8, uint16, uint32, uint64: - fieldValue := configValue.Field(i).Uint() + fieldValue := reflect.Indirect(configValue.Field(i)).Uint() m.viper.SetDefault(name, uint(fieldValue)) flags.UintP(name, shorthand, uint(fieldValue), description) case float32, float64: - fieldValue := configValue.Field(i).Float() + fieldValue := reflect.Indirect(configValue.Field(i)).Float() m.viper.SetDefault(name, fieldValue) flags.Float64P(name, shorthand, fieldValue, description) From 5d31976911a44606c0490645f3d28d20b099907b Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 12 Feb 2019 21:01:36 +0100 Subject: [PATCH 14/40] util: Fix config package test --- pkg/config/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 17f442223f..bfba7e2267 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -129,7 +129,7 @@ func TestNilConfig(t *testing.T) { func TestInvalidConfig(t *testing.T) { a := assertions.New(t) - config := InitializeWithDefaults("invalid", "invalid", "invalid") + config := InitializeWithDefaults("invalid", "invalid", struct{}{}) a.So(config, should.NotBeNil) } From cef73e40a209b9dc55fa9697a2e5c83da85f5d2b Mon Sep 17 00:00:00 2001 From: Hylke Visser Date: Wed, 13 Feb 2019 15:12:31 +0100 Subject: [PATCH 15/40] cli: Add flag support for google/protobuf/wrappers --- cmd/ttn-lw-cli/internal/util/flags.go | 103 ++++++++++++++++++++------ 1 file changed, 82 insertions(+), 21 deletions(-) diff --git a/cmd/ttn-lw-cli/internal/util/flags.go b/cmd/ttn-lw-cli/internal/util/flags.go index 8725532a90..7ee307253e 100644 --- a/cmd/ttn-lw-cli/internal/util/flags.go +++ b/cmd/ttn-lw-cli/internal/util/flags.go @@ -23,6 +23,7 @@ import ( "time" "github.com/gogo/protobuf/proto" + "github.com/gogo/protobuf/types" "github.com/spf13/pflag" "go.thethings.network/lorawan-stack/pkg/errors" ) @@ -73,11 +74,18 @@ func FieldMaskFlags(v interface{}, prefix ...string) *pflag.FlagSet { } func isAtomicType(t reflect.Type, maskOnly bool) bool { - switch t.Name() { - case "Time", "Duration": - return true - } - if t.PkgPath() == "go.thethings.network/lorawan-stack/pkg/ttnpb" { + switch t.PkgPath() { + case "time": + switch t.Name() { + case "Time", "Duration": + return true + } + case "github.com/gogo/protobuf/types": + switch t.Name() { + case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value", "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue": + return true + } + case "go.thethings.network/lorawan-stack/pkg/ttnpb": switch t.Name() { case "Picture": return true @@ -183,11 +191,35 @@ func addField(fs *pflag.FlagSet, name string, t reflect.Type, maskOnly bool) { } else if (t.Kind() == reflect.Slice || t.Kind() == reflect.Array) && t.Elem().Kind() == reflect.Uint8 { fs.String(name, "", "(hex)") } else { - switch t.Name() { - case "Time": - fs.String(name, "", "(YYYY-MM-DDTHH:MM:SSZ)") - case "Duration": - fs.Duration(name, 0, "(1h2m3s)") + switch t.PkgPath() { + case "time": + switch t.Name() { + case "Time": + fs.String(name, "", "(YYYY-MM-DDTHH:MM:SSZ)") + case "Duration": + fs.Duration(name, 0, "(1h2m3s)") + } + case "github.com/gogo/protobuf/types": + switch t.Name() { + case "DoubleValue": + fs.Float64(name, 0, "") + case "FloatValue": + fs.Float32(name, 0, "") + case "Int64Value": + fs.Int64(name, 0, "") + case "UInt64Value": + fs.Uint64(name, 0, "") + case "Int32Value": + fs.Int32(name, 0, "") + case "UInt32Value": + fs.Uint32(name, 0, "") + case "BoolValue": + fs.Bool(name, false, "") + case "StringValue": + fs.String(name, "", "") + case "BytesValue": + fs.String(name, "", "(hex)") + } default: fmt.Printf("flags: %s.%s not yet supported (%s)\n", t.PkgPath(), t.Name(), name) } @@ -326,22 +358,51 @@ func setField(rv reflect.Value, path []string, v reflect.Value) error { } } return fmt.Errorf(`invalid value "%s" for %s`, v.String(), ft.Name()) - case ft.PkgPath() == "time" && ft.Name() == "Time" && vt.Kind() == reflect.String: - var t time.Time - var err error - if v.String() != "" { - t, err = time.Parse(time.RFC3339Nano, v.String()) + case ft.PkgPath() == "time": + switch { + case ft.Name() == "Time" && vt.Kind() == reflect.String: + var t time.Time + var err error + if v.String() != "" { + t, err = time.Parse(time.RFC3339Nano, v.String()) + if err != nil { + return err + } + } + field.Set(reflect.ValueOf(t)) + case ft.Name() == "Duration" && vt.Kind() == reflect.String: + d, err := time.ParseDuration(v.String()) if err != nil { return err } + field.Set(reflect.ValueOf(d)) } - field.Set(reflect.ValueOf(t)) - case ft.PkgPath() == "time" && ft.Name() == "Duration" && vt.Kind() == reflect.String: - d, err := time.ParseDuration(v.String()) - if err != nil { - return err + case ft.PkgPath() == "github.com/gogo/protobuf/types": + switch ft.Name() { + case "DoubleValue": + field.Set(reflect.ValueOf(types.DoubleValue{Value: v.Float()})) + case "FloatValue": + field.Set(reflect.ValueOf(types.FloatValue{Value: float32(v.Float())})) + case "Int64Value": + field.Set(reflect.ValueOf(types.Int64Value{Value: v.Int()})) + case "UInt64Value": + field.Set(reflect.ValueOf(types.UInt64Value{Value: v.Uint()})) + case "Int32Value": + field.Set(reflect.ValueOf(types.Int32Value{Value: int32(v.Int())})) + case "UInt32Value": + field.Set(reflect.ValueOf(types.UInt32Value{Value: uint32(v.Uint())})) + case "BoolValue": + field.Set(reflect.ValueOf(types.BoolValue{Value: v.Bool()})) + case "StringValue": + field.Set(reflect.ValueOf(types.StringValue{Value: v.String()})) + case "BytesValue": + s := strings.TrimPrefix(v.String(), "0x") + buf, err := hex.DecodeString(s) + if err != nil { + return err + } + field.Set(reflect.ValueOf(types.BytesValue{Value: buf})) } - field.Set(reflect.ValueOf(d)) case ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && vt.Kind() == reflect.String: s := strings.TrimPrefix(v.String(), "0x") buf, err := hex.DecodeString(s) From 42add61c37f8b5308bfa1ecf81111a4d083c5be6 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Thu, 14 Feb 2019 20:18:05 +0100 Subject: [PATCH 16/40] api: Ensure consistency of MACSettings with DeviceProfile --- api/api.md | 70 +- api/api.swagger.json | 146 +- api/end_device.proto | 179 +- pkg/ttnpb/end_device.pb.fm.go | 649 ++++-- pkg/ttnpb/end_device.pb.go | 3153 +++++++++++++++++--------- pkg/ttnpb/end_device.validator.pb.go | 95 +- pkg/ttnpb/end_device_populate.go | 3 +- 7 files changed, 2816 insertions(+), 1479 deletions(-) diff --git a/api/api.md b/api/api.md index bcd7a51fb1..c7c4335903 100644 --- a/api/api.md +++ b/api/api.md @@ -121,7 +121,9 @@ - [MACParameters](#ttn.lorawan.v3.MACParameters) - [MACParameters.Channel](#ttn.lorawan.v3.MACParameters.Channel) - [MACSettings](#ttn.lorawan.v3.MACSettings) + - [MACSettings.AggregatedDutyCycleValue](#ttn.lorawan.v3.MACSettings.AggregatedDutyCycleValue) - [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) + - [MACSettings.PingSlotPeriodValue](#ttn.lorawan.v3.MACSettings.PingSlotPeriodValue) - [MACSettings.RxDelayValue](#ttn.lorawan.v3.MACSettings.RxDelayValue) - [MACState](#ttn.lorawan.v3.MACState) - [MACState.JoinAccept](#ttn.lorawan.v3.MACState.JoinAccept) @@ -1524,16 +1526,13 @@ SDKs are responsible for combining (if desired) the three. | lorawan_version | [MACVersion](#ttn.lorawan.v3.MACVersion) | | LoRaWAN MAC version. Stored in Network Server. Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. | | lorawan_phy_version | [PHYVersion](#ttn.lorawan.v3.PHYVersion) | | LoRaWAN PHY version. Stored in Network Server. Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. | | frequency_plan_id | [string](#string) | | ID of the frequency plan used by this device. Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. | -| default_mac_parameters | [MACParameters](#ttn.lorawan.v3.MACParameters) | | Default MAC layer parameters, to which device is reset by default (e.g. on join or ResetInd). Stored in Network Server. Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. | | min_frequency | [uint64](#uint64) | | Minimum frequency the device is capable of using (Hz). Stored in Network Server. Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. | | max_frequency | [uint64](#uint64) | | Maximum frequency the device is capable of using (Hz). Stored in Network Server. Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. | -| resets_f_cnt | [bool](#bool) | | Whether the device resets the frame counters (not LoRaWAN compliant). Stored in Network Server. Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. | -| uses_32_bit_f_cnt | [bool](#bool) | | Whether the device uses 32-bit frame counters. Stored in Network Server. Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. | | supports_join | [bool](#bool) | | The device supports join (it's OTAA). Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. | -| resets_join_nonces | [bool](#bool) | | Whether the device resets the join and dev nonces (not LoRaWAN 1.1 compliant). Stored in Network Server. Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. | +| resets_join_nonces | [bool](#bool) | | Whether the device resets the join and dev nonces (not LoRaWAN 1.1 compliant). Stored in Join Server. Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. | | root_keys | [RootKeys](#ttn.lorawan.v3.RootKeys) | | Device root keys. Stored in Join Server. | | net_id | [bytes](#bytes) | | Home NetID. Stored in Join Server. | -| mac_settings | [MACSettings](#ttn.lorawan.v3.MACSettings) | | Settings for how the Network Server handles MAC for this device. Stored in Network Server. | +| mac_settings | [MACSettings](#ttn.lorawan.v3.MACSettings) | | Settings for how the Network Server handles MAC layer for this device. Stored in Network Server. | | mac_state | [MACState](#ttn.lorawan.v3.MACState) | | MAC state of the device. Stored in Network Server. | | session | [Session](#ttn.lorawan.v3.Session) | | Current session of the device. Stored in Network Server and Application Server. | | pending_session | [Session](#ttn.lorawan.v3.Session) | | Pending session. Stored in Network Server and Application Server until RekeyInd is received. | @@ -1641,11 +1640,10 @@ Template for creating end devices. | photos | [string](#string) | repeated | Photos contains file names of device photos. | | supports_class_b | [bool](#bool) | | Whether the device supports class B. | | supports_class_c | [bool](#bool) | | Whether the device supports class C. | -| default_mac_parameters | [MACParameters](#ttn.lorawan.v3.MACParameters) | | Default MAC layer parameters, to which device is reset by default (e.g. on join or ResetInd). | +| default_mac_settings | [MACSettings](#ttn.lorawan.v3.MACSettings) | | Default MAC layer settings of the device. | | min_frequency | [uint64](#uint64) | | Minimum frequency the device is capable of using (Hz). | | max_frequency | [uint64](#uint64) | | Maximum frequency the device is capable of using (Hz). | | resets_f_cnt | [bool](#bool) | | Whether the device resets the frame counters (not LoRaWAN compliant). | -| uses_32_bit_f_cnt | [bool](#bool) | | Whether the device uses 32-bit frame counters. | | supports_join | [bool](#bool) | | The device supports join (it's OTAA). | | resets_join_nonces | [bool](#bool) | | Whether the device resets the join and dev nonces (not LoRaWAN 1.1 compliant). | | default_formatters | [MessagePayloadFormatters](#ttn.lorawan.v3.MessagePayloadFormatters) | | Default formatters defining the payload formats for this end device. | @@ -1744,13 +1742,13 @@ This is used internally by the Network Server and is read only. | rx1_data_rate_offset | [uint32](#uint32) | | Data rate offset for Rx1. | | rx2_data_rate_index | [DataRateIndex](#ttn.lorawan.v3.DataRateIndex) | | Data rate index for Rx2. | | rx2_frequency | [uint64](#uint64) | | Frequency for Rx2 (Hz). | +| max_duty_cycle | [AggregatedDutyCycle](#ttn.lorawan.v3.AggregatedDutyCycle) | | Maximum uplink duty cycle (of all channels). | | rejoin_time_periodicity | [RejoinTimeExponent](#ttn.lorawan.v3.RejoinTimeExponent) | | Time within which a rejoin-request must be sent. | | rejoin_count_periodicity | [RejoinCountExponent](#ttn.lorawan.v3.RejoinCountExponent) | | Message count within which a rejoin-request must be sent. | -| max_duty_cycle | [AggregatedDutyCycle](#ttn.lorawan.v3.AggregatedDutyCycle) | | Maximum uplink duty cycle (of all channels). | -| channels | [MACParameters.Channel](#ttn.lorawan.v3.MACParameters.Channel) | repeated | Configured uplink channels and optionally Rx1 frequency. | | ping_slot_frequency | [uint64](#uint64) | | Frequency of the class B ping slot (Hz). | | ping_slot_data_rate_index | [DataRateIndex](#ttn.lorawan.v3.DataRateIndex) | | Data rate index of the class B ping slot. | | beacon_frequency | [uint64](#uint64) | | Frequency of the class B beacon (Hz). | +| channels | [MACParameters.Channel](#ttn.lorawan.v3.MACParameters.Channel) | repeated | Configured uplink channels and optionally Rx1 frequency. | @@ -1784,15 +1782,42 @@ This is used internally by the Network Server and is read only. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| use_adr | [google.protobuf.BoolValue](#google.protobuf.BoolValue) | | | +| class_b_timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | Maximum delay for the device to answer a MAC request or a confirmed downlink frame. Must be set if the device supports class B. | +| ping_slot_periodicity | [MACSettings.PingSlotPeriodValue](#ttn.lorawan.v3.MACSettings.PingSlotPeriodValue) | | Periodicity of the class B ping slot. Must be set if the device supports class B. | +| ping_slot_data_rate_index | [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) | | Data rate index of the class B ping slot. Must be set if the device supports class B. | +| ping_slot_frequency | [uint64](#uint64) | | Frequency of the class B ping slot (Hz). Must be set if the device supports class B. | +| class_c_timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | Maximum delay for the device to answer a MAC request or a confirmed downlink frame. Must be set if the device supports class C. | +| rx1_delay | [MACSettings.RxDelayValue](#ttn.lorawan.v3.MACSettings.RxDelayValue) | | Class A Rx1 delay. Must be set if the device is ABP. | +| rx1_data_rate_offset | [google.protobuf.UInt32Value](#google.protobuf.UInt32Value) | | Rx1 data rate offset. Must be set if the device is ABP. | +| rx2_data_rate_index | [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) | | Data rate index for Rx2. Must be set if the device is ABP. | +| rx2_frequency | [uint64](#uint64) | | Frequency for Rx2 (Hz). Must be set if the device is ABP. | +| factory_preset_frequencies | [uint64](#uint64) | repeated | List of factory-preset frequencies. Must be set if the device is ABP. | +| max_duty_cycle | [MACSettings.AggregatedDutyCycleValue](#ttn.lorawan.v3.MACSettings.AggregatedDutyCycleValue) | | Maximum uplink duty cycle (of all channels). | +| supports_32_bit_f_cnt | [google.protobuf.BoolValue](#google.protobuf.BoolValue) | | Whether the device supports 32-bit frame counters. Must be set if the device MAC version is 1.0. | +| use_adr | [google.protobuf.BoolValue](#google.protobuf.BoolValue) | | Whether the Network Server should use ADR for the device. | | adr_margin | [google.protobuf.FloatValue](#google.protobuf.FloatValue) | | The ADR margin tells the network server how much margin it should add in ADR requests. A bigger margin is less efficient, but gives a better chance of successful reception. | -| class_b_timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | Deadline for the device to respond to requests from the Network Server. | -| class_c_timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | Deadline for the device to respond to requests from the Network Server. | +| resets_f_cnt | [google.protobuf.BoolValue](#google.protobuf.BoolValue) | | Whether the device resets the frame counters (not LoRaWAN compliant). | | status_time_periodicity | [google.protobuf.Duration](#google.protobuf.Duration) | | The interval after which a DevStatusReq MACCommand shall be sent. | | status_count_periodicity | [google.protobuf.UInt32Value](#google.protobuf.UInt32Value) | | Number of uplink messages after which a DevStatusReq MACCommand shall be sent. | -| rx1_delay | [MACSettings.RxDelayValue](#ttn.lorawan.v3.MACSettings.RxDelayValue) | | | -| rx2_data_rate_index | [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) | | | -| rx2_frequency | [google.protobuf.UInt64Value](#google.protobuf.UInt64Value) | | | +| desired_rx1_delay | [MACSettings.RxDelayValue](#ttn.lorawan.v3.MACSettings.RxDelayValue) | | The Rx1 delay Network Server should configure device to use via MAC commands or Join-Accept. | +| desired_rx1_data_rate_offset | [google.protobuf.UInt32Value](#google.protobuf.UInt32Value) | | The Rx1 data rate offset Network Server should configure device to use via MAC commands or Join-Accept. | +| desired_rx2_data_rate_index | [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) | | The Rx2 data rate index Network Server should configure device to use via MAC commands or Join-Accept. | +| desired_rx2_frequency | [uint64](#uint64) | | The Rx2 frequency index Network Server should configure device to use via MAC commands. | + + + + + + + + +### MACSettings.AggregatedDutyCycleValue + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| value | [AggregatedDutyCycle](#ttn.lorawan.v3.AggregatedDutyCycle) | | | @@ -1814,6 +1839,21 @@ This is used internally by the Network Server and is read only. + + +### MACSettings.PingSlotPeriodValue + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| value | [PingSlotPeriod](#ttn.lorawan.v3.PingSlotPeriod) | | | + + + + + + ### MACSettings.RxDelayValue diff --git a/api/api.swagger.json b/api/api.swagger.json index 689f523a18..9a0b9b3f3e 100644 --- a/api/api.swagger.json +++ b/api/api.swagger.json @@ -4870,6 +4870,14 @@ } } }, + "MACSettingsAggregatedDutyCycleValue": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/v3AggregatedDutyCycle" + } + } + }, "MACSettingsDataRateIndexValue": { "type": "object", "properties": { @@ -4878,6 +4886,14 @@ } } }, + "MACSettingsPingSlotPeriodValue": { + "type": "object", + "properties": { + "value": { + "$ref": "#/definitions/v3PingSlotPeriod" + } + } + }, "MACSettingsRxDelayValue": { "type": "object", "properties": { @@ -6332,10 +6348,6 @@ "type": "string", "description": "ID of the frequency plan used by this device.\nCopied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any." }, - "default_mac_parameters": { - "$ref": "#/definitions/v3MACParameters", - "description": "Default MAC layer parameters, to which device is reset by default (e.g. on join or ResetInd). Stored in Network Server.\nCopied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any." - }, "min_frequency": { "type": "string", "format": "uint64", @@ -6346,16 +6358,6 @@ "format": "uint64", "description": "Maximum frequency the device is capable of using (Hz). Stored in Network Server.\nCopied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any." }, - "resets_f_cnt": { - "type": "boolean", - "format": "boolean", - "description": "Whether the device resets the frame counters (not LoRaWAN compliant). Stored in Network Server.\nCopied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any." - }, - "uses_32_bit_f_cnt": { - "type": "boolean", - "format": "boolean", - "description": "Whether the device uses 32-bit frame counters. Stored in Network Server.\nCopied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any." - }, "supports_join": { "type": "boolean", "format": "boolean", @@ -6364,7 +6366,7 @@ "resets_join_nonces": { "type": "boolean", "format": "boolean", - "description": "Whether the device resets the join and dev nonces (not LoRaWAN 1.1 compliant). Stored in Network Server.\nCopied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any." + "description": "Whether the device resets the join and dev nonces (not LoRaWAN 1.1 compliant). Stored in Join Server.\nCopied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any." }, "root_keys": { "$ref": "#/definitions/v3RootKeys", @@ -6377,7 +6379,7 @@ }, "mac_settings": { "$ref": "#/definitions/v3MACSettings", - "description": "Settings for how the Network Server handles MAC for this device. Stored in Network Server." + "description": "Settings for how the Network Server handles MAC layer for this device. Stored in Network Server." }, "mac_state": { "$ref": "#/definitions/v3MACState", @@ -7343,6 +7345,10 @@ "format": "uint64", "description": "Frequency for Rx2 (Hz)." }, + "max_duty_cycle": { + "$ref": "#/definitions/v3AggregatedDutyCycle", + "description": "Maximum uplink duty cycle (of all channels)." + }, "rejoin_time_periodicity": { "$ref": "#/definitions/v3RejoinTimeExponent", "description": "Time within which a rejoin-request must be sent." @@ -7351,17 +7357,6 @@ "$ref": "#/definitions/v3RejoinCountExponent", "description": "Message count within which a rejoin-request must be sent." }, - "max_duty_cycle": { - "$ref": "#/definitions/v3AggregatedDutyCycle", - "description": "Maximum uplink duty cycle (of all channels)." - }, - "channels": { - "type": "array", - "items": { - "$ref": "#/definitions/v3MACParametersChannel" - }, - "description": "Configured uplink channels and optionally Rx1 frequency." - }, "ping_slot_frequency": { "type": "string", "format": "uint64", @@ -7375,6 +7370,13 @@ "type": "string", "format": "uint64", "description": "Frequency of the class B beacon (Hz)." + }, + "channels": { + "type": "array", + "items": { + "$ref": "#/definitions/v3MACParametersChannel" + }, + "description": "Configured uplink channels and optionally Rx1 frequency." } }, "description": "MACParameters represent the parameters of the device's MAC layer (active or desired).\nThis is used internally by the Network Server and is read only." @@ -7429,22 +7431,76 @@ "v3MACSettings": { "type": "object", "properties": { + "class_b_timeout": { + "type": "string", + "description": "Maximum delay for the device to answer a MAC request or a confirmed downlink frame.\nMust be set if the device supports class B." + }, + "ping_slot_periodicity": { + "$ref": "#/definitions/MACSettingsPingSlotPeriodValue", + "description": "Periodicity of the class B ping slot.\nMust be set if the device supports class B." + }, + "ping_slot_data_rate_index": { + "$ref": "#/definitions/MACSettingsDataRateIndexValue", + "description": "Data rate index of the class B ping slot.\nMust be set if the device supports class B." + }, + "ping_slot_frequency": { + "type": "string", + "format": "uint64", + "description": "Frequency of the class B ping slot (Hz).\nMust be set if the device supports class B." + }, + "class_c_timeout": { + "type": "string", + "description": "Maximum delay for the device to answer a MAC request or a confirmed downlink frame.\nMust be set if the device supports class C." + }, + "rx1_delay": { + "$ref": "#/definitions/MACSettingsRxDelayValue", + "description": "Class A Rx1 delay.\nMust be set if the device is ABP." + }, + "rx1_data_rate_offset": { + "type": "integer", + "format": "int64", + "description": "Rx1 data rate offset.\nMust be set if the device is ABP." + }, + "rx2_data_rate_index": { + "$ref": "#/definitions/MACSettingsDataRateIndexValue", + "description": "Data rate index for Rx2.\nMust be set if the device is ABP." + }, + "rx2_frequency": { + "type": "string", + "format": "uint64", + "description": "Frequency for Rx2 (Hz).\nMust be set if the device is ABP." + }, + "factory_preset_frequencies": { + "type": "array", + "items": { + "type": "string", + "format": "uint64" + }, + "description": "List of factory-preset frequencies.\nMust be set if the device is ABP." + }, + "max_duty_cycle": { + "$ref": "#/definitions/MACSettingsAggregatedDutyCycleValue", + "description": "Maximum uplink duty cycle (of all channels)." + }, + "supports_32_bit_f_cnt": { + "type": "boolean", + "format": "boolean", + "description": "Whether the device supports 32-bit frame counters.\nMust be set if the device MAC version is 1.0." + }, "use_adr": { "type": "boolean", - "format": "boolean" + "format": "boolean", + "description": "Whether the Network Server should use ADR for the device." }, "adr_margin": { "type": "number", "format": "float", "description": "The ADR margin tells the network server how much margin it should add in ADR requests.\nA bigger margin is less efficient, but gives a better chance of successful reception." }, - "class_b_timeout": { - "type": "string", - "description": "Deadline for the device to respond to requests from the Network Server." - }, - "class_c_timeout": { - "type": "string", - "description": "Deadline for the device to respond to requests from the Network Server." + "resets_f_cnt": { + "type": "boolean", + "format": "boolean", + "description": "Whether the device resets the frame counters (not LoRaWAN compliant)." }, "status_time_periodicity": { "type": "string", @@ -7455,15 +7511,23 @@ "format": "int64", "description": "Number of uplink messages after which a DevStatusReq MACCommand shall be sent." }, - "rx1_delay": { - "$ref": "#/definitions/MACSettingsRxDelayValue" + "desired_rx1_delay": { + "$ref": "#/definitions/MACSettingsRxDelayValue", + "description": "The Rx1 delay Network Server should configure device to use via MAC commands or Join-Accept." }, - "rx2_data_rate_index": { - "$ref": "#/definitions/MACSettingsDataRateIndexValue" + "desired_rx1_data_rate_offset": { + "type": "integer", + "format": "int64", + "description": "The Rx1 data rate offset Network Server should configure device to use via MAC commands or Join-Accept." }, - "rx2_frequency": { + "desired_rx2_data_rate_index": { + "$ref": "#/definitions/MACSettingsDataRateIndexValue", + "description": "The Rx2 data rate index Network Server should configure device to use via MAC commands or Join-Accept." + }, + "desired_rx2_frequency": { "type": "string", - "format": "uint64" + "format": "uint64", + "description": "The Rx2 frequency index Network Server should configure device to use via MAC commands." } } }, diff --git a/api/end_device.proto b/api/end_device.proto index 4223028488..db8258e91f 100644 --- a/api/end_device.proto +++ b/api/end_device.proto @@ -81,12 +81,18 @@ message MACParameters { DataRateIndex rx2_data_rate_index = 11; // Frequency for Rx2 (Hz). uint64 rx2_frequency = 12; + // Maximum uplink duty cycle (of all channels). + AggregatedDutyCycle max_duty_cycle = 13; // Time within which a rejoin-request must be sent. - RejoinTimeExponent rejoin_time_periodicity = 13; + RejoinTimeExponent rejoin_time_periodicity = 14; // Message count within which a rejoin-request must be sent. - RejoinCountExponent rejoin_count_periodicity = 14; - // Maximum uplink duty cycle (of all channels). - AggregatedDutyCycle max_duty_cycle = 15; + RejoinCountExponent rejoin_count_periodicity = 15; + // Frequency of the class B ping slot (Hz). + uint64 ping_slot_frequency = 16; + // Data rate index of the class B ping slot. + DataRateIndex ping_slot_data_rate_index = 17; + // Frequency of the class B beacon (Hz). + uint64 beacon_frequency = 18; message Channel { option (gogoproto.populate) = false; @@ -103,14 +109,7 @@ message MACParameters { bool enable_uplink = 5; } // Configured uplink channels and optionally Rx1 frequency. - repeated Channel channels = 16; - - // Frequency of the class B ping slot (Hz). - uint64 ping_slot_frequency = 17; - // Data rate index of the class B ping slot. - DataRateIndex ping_slot_data_rate_index = 18; - // Frequency of the class B beacon (Hz). - uint64 beacon_frequency = 19; + repeated Channel channels = 19; } message EndDeviceBrand { @@ -156,16 +155,14 @@ message EndDeviceVersion { bool supports_class_b = 6; // Whether the device supports class C. bool supports_class_c = 7; - // Default MAC layer parameters, to which device is reset by default (e.g. on join or ResetInd). - MACParameters default_mac_parameters = 8 [(gogoproto.customname) = "DefaultMACParameters"]; + // Default MAC layer settings of the device. + MACSettings default_mac_settings = 8 [(gogoproto.customname) = "DefaultMACSettings"]; // Minimum frequency the device is capable of using (Hz). uint64 min_frequency = 9; // Maximum frequency the device is capable of using (Hz). uint64 max_frequency = 10; // Whether the device resets the frame counters (not LoRaWAN compliant). bool resets_f_cnt = 11; - // Whether the device uses 32-bit frame counters. - bool uses_32_bit_f_cnt = 12 [(gogoproto.customname) = "Uses32BitFCnt"]; // The device supports join (it's OTAA). bool supports_join = 13; // Whether the device resets the join and dev nonces (not LoRaWAN 1.1 compliant). @@ -176,30 +173,79 @@ message EndDeviceVersion { } message MACSettings { - google.protobuf.BoolValue use_adr = 1 [(gogoproto.customname) = "UseADR"]; - // The ADR margin tells the network server how much margin it should add in ADR requests. - // A bigger margin is less efficient, but gives a better chance of successful reception. - google.protobuf.FloatValue adr_margin = 2 [(gogoproto.customname) = "ADRMargin"]; - // Deadline for the device to respond to requests from the Network Server. - google.protobuf.Duration class_b_timeout = 3 [(gogoproto.stdduration) = true]; - // Deadline for the device to respond to requests from the Network Server. - google.protobuf.Duration class_c_timeout = 4 [(gogoproto.stdduration) = true]; - // The interval after which a DevStatusReq MACCommand shall be sent. - google.protobuf.Duration status_time_periodicity = 5 [(gogoproto.stdduration) = true]; - // Number of uplink messages after which a DevStatusReq MACCommand shall be sent. - google.protobuf.UInt32Value status_count_periodicity = 6; - + message DataRateIndexValue { + DataRateIndex value = 1; + } + message PingSlotPeriodValue { + PingSlotPeriod value = 1; + } + message AggregatedDutyCycleValue { + AggregatedDutyCycle value = 1; + } message RxDelayValue { RxDelay value = 1; } - RxDelayValue rx1_delay = 7; - message DataRateIndexValue { - DataRateIndex value = 1; - } + // Maximum delay for the device to answer a MAC request or a confirmed downlink frame. + // Must be set if the device supports class B. + google.protobuf.Duration class_b_timeout = 1 [(gogoproto.stdduration) = true]; + // Periodicity of the class B ping slot. + // Must be set if the device supports class B. + PingSlotPeriodValue ping_slot_periodicity = 2; + // Data rate index of the class B ping slot. + // Must be set if the device supports class B. + DataRateIndexValue ping_slot_data_rate_index = 3; + // Frequency of the class B ping slot (Hz). + // Must be set if the device supports class B. + uint64 ping_slot_frequency = 4; + + // Maximum delay for the device to answer a MAC request or a confirmed downlink frame. + // Must be set if the device supports class C. + google.protobuf.Duration class_c_timeout = 5 [(gogoproto.stdduration) = true]; + + // Class A Rx1 delay. + // Must be set if the device is ABP. + RxDelayValue rx1_delay = 6; + // Rx1 data rate offset. + // Must be set if the device is ABP. + google.protobuf.UInt32Value rx1_data_rate_offset = 7; + // Data rate index for Rx2. + // Must be set if the device is ABP. DataRateIndexValue rx2_data_rate_index = 8; + // Frequency for Rx2 (Hz). + // Must be set if the device is ABP. + uint64 rx2_frequency = 9; + // List of factory-preset frequencies. + // Must be set if the device is ABP. + repeated uint64 factory_preset_frequencies = 10; + + // Maximum uplink duty cycle (of all channels). + AggregatedDutyCycleValue max_duty_cycle = 11; - google.protobuf.UInt64Value rx2_frequency = 9; + // Whether the device supports 32-bit frame counters. + // Must be set if the device MAC version is 1.0. + google.protobuf.BoolValue supports_32_bit_f_cnt = 12 [(gogoproto.customname) = "Supports32BitFCnt"]; + + // Whether the Network Server should use ADR for the device. + google.protobuf.BoolValue use_adr = 13 [(gogoproto.customname) = "UseADR"]; + // The ADR margin tells the network server how much margin it should add in ADR requests. + // A bigger margin is less efficient, but gives a better chance of successful reception. + google.protobuf.FloatValue adr_margin = 14 [(gogoproto.customname) = "ADRMargin"]; + // Whether the device resets the frame counters (not LoRaWAN compliant). + google.protobuf.BoolValue resets_f_cnt = 15; + // The interval after which a DevStatusReq MACCommand shall be sent. + google.protobuf.Duration status_time_periodicity = 16 [(gogoproto.stdduration) = true]; + // Number of uplink messages after which a DevStatusReq MACCommand shall be sent. + google.protobuf.UInt32Value status_count_periodicity = 17; + + // The Rx1 delay Network Server should configure device to use via MAC commands or Join-Accept. + RxDelayValue desired_rx1_delay = 18; + // The Rx1 data rate offset Network Server should configure device to use via MAC commands or Join-Accept. + google.protobuf.UInt32Value desired_rx1_data_rate_offset = 19; + // The Rx2 data rate index Network Server should configure device to use via MAC commands or Join-Accept. + DataRateIndexValue desired_rx2_data_rate_index = 20; + // The Rx2 frequency index Network Server should configure device to use via MAC commands. + uint64 desired_rx2_frequency = 21; } // MACState represents the state of MAC layer of the device. @@ -325,98 +371,89 @@ message EndDevice { // ID of the frequency plan used by this device. // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. string frequency_plan_id = 17 [(gogoproto.customname) = "FrequencyPlanID"]; - // Default MAC layer parameters, to which device is reset by default (e.g. on join or ResetInd). Stored in Network Server. - // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - MACParameters default_mac_parameters = 18 [(gogoproto.customname) = "DefaultMACParameters"]; // Minimum frequency the device is capable of using (Hz). Stored in Network Server. // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - uint64 min_frequency = 19; + uint64 min_frequency = 18; // Maximum frequency the device is capable of using (Hz). Stored in Network Server. // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - uint64 max_frequency = 20; - // Whether the device resets the frame counters (not LoRaWAN compliant). Stored in Network Server. - // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - bool resets_f_cnt = 21; - // Whether the device uses 32-bit frame counters. Stored in Network Server. - // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - bool uses_32_bit_f_cnt = 22 [(gogoproto.customname) = "Uses32BitFCnt"]; + uint64 max_frequency = 19; // The device supports join (it's OTAA). // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - bool supports_join = 23; - // Whether the device resets the join and dev nonces (not LoRaWAN 1.1 compliant). Stored in Network Server. + bool supports_join = 20; + // Whether the device resets the join and dev nonces (not LoRaWAN 1.1 compliant). Stored in Join Server. // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - bool resets_join_nonces = 24; + bool resets_join_nonces = 21; // Device root keys. Stored in Join Server. - RootKeys root_keys = 25; + RootKeys root_keys = 22; // Home NetID. Stored in Join Server. - bytes net_id = 26 [(gogoproto.customtype) = "go.thethings.network/lorawan-stack/pkg/types.NetID", (gogoproto.customname) = "NetID"]; - // Settings for how the Network Server handles MAC for this device. Stored in Network Server. - MACSettings mac_settings = 27 [(gogoproto.customname) = "MACSettings"]; + bytes net_id = 23 [(gogoproto.customtype) = "go.thethings.network/lorawan-stack/pkg/types.NetID", (gogoproto.customname) = "NetID"]; + // Settings for how the Network Server handles MAC layer for this device. Stored in Network Server. + MACSettings mac_settings = 24 [(gogoproto.customname) = "MACSettings"]; // MAC state of the device. Stored in Network Server. - MACState mac_state = 28 [(gogoproto.customname) = "MACState"]; + MACState mac_state = 25 [(gogoproto.customname) = "MACState"]; // Current session of the device. Stored in Network Server and Application Server. - Session session = 29; + Session session = 26; // Pending session. Stored in Network Server and Application Server until RekeyInd is received. - Session pending_session = 30; + Session pending_session = 27; // Last DevNonce used. // This field is only used for devices using LoRaWAN version 1.1 and later. // Stored in Join Server. - uint32 last_dev_nonce = 31; + uint32 last_dev_nonce = 28; // Used DevNonces sorted in ascending order. // This field is only used for devices using LoRaWAN versions preceding 1.1. // Stored in Join Server. - repeated uint32 used_dev_nonces = 32; + repeated uint32 used_dev_nonces = 29; // Last JoinNonce/AppNonce(for devices using LoRaWAN versions preceding 1.1) used. // Stored in Join Server. - uint32 last_join_nonce = 33; + uint32 last_join_nonce = 30; // Last Rejoin counter value used (type 0/2). // Stored in Join Server. - uint32 last_rj_count_0 = 34 [(gogoproto.customname) = "LastRJCount0"]; + uint32 last_rj_count_0 = 31 [(gogoproto.customname) = "LastRJCount0"]; // Last Rejoin counter value used (type 1). // Stored in Join Server. - uint32 last_rj_count_1 = 35 [(gogoproto.customname) = "LastRJCount1"]; + uint32 last_rj_count_1 = 32 [(gogoproto.customname) = "LastRJCount1"]; // Time when last DevStatus MAC command was received. // Stored in Network Server. - google.protobuf.Timestamp last_dev_status_received_at = 36 [(gogoproto.stdtime) = true]; + google.protobuf.Timestamp last_dev_status_received_at = 33 [(gogoproto.stdtime) = true]; // The power state of the device; whether it is battery-powered or connected to an external power source. // Received via the DevStatus MAC command at status_received_at. // Stored in Network Server. - PowerState power_state = 37; + PowerState power_state = 34; // Latest-known battery percentage of the device. // Received via the DevStatus MAC command at last_dev_status_received_at or earlier. // Stored in Network Server. - float battery_percentage = 38; + float battery_percentage = 35; // Demodulation signal-to-noise ratio (dB). // Received via the DevStatus MAC command at last_dev_status_received_at. // Stored in Network Server. - int32 downlink_margin = 39; + int32 downlink_margin = 36; // Recent uplink messages with ADR bit set to 1 sorted by time. Stored in Network Server. // The field is reset each time an uplink message carrying MACPayload is received with ADR bit set to 0. // The number of messages stored is in the range [0,20]; - repeated UplinkMessage recent_adr_uplinks = 40 [(gogoproto.customname) = "RecentADRUplinks"]; + repeated UplinkMessage recent_adr_uplinks = 37 [(gogoproto.customname) = "RecentADRUplinks"]; // Recent uplink messages sorted by time. Stored in Network Server. // The number of messages stored may depend on configuration. - repeated UplinkMessage recent_uplinks = 41; + repeated UplinkMessage recent_uplinks = 38; // Recent downlink messages sorted by time. Stored in Network Server. // The number of messages stored may depend on configuration. - repeated DownlinkMessage recent_downlinks = 42; + repeated DownlinkMessage recent_downlinks = 39; // Queued Application downlink messages. Stored in Application Server, // which sets them on the Network Server. - repeated ApplicationDownlink queued_application_downlinks = 43; + repeated ApplicationDownlink queued_application_downlinks = 40; // The payload formatters for this end device. Stored in Application Server. // Copied on creation from template identified by version_ids. - MessagePayloadFormatters formatters = 44; + MessagePayloadFormatters formatters = 41; // ID of the provisioner. Stored in Join Server. - string provisioner_id = 45 [(gogoproto.customname) = "ProvisionerID", (validator.field) = {regex: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$|^$", length_lt: 37}]; + string provisioner_id = 42 [(gogoproto.customname) = "ProvisionerID", (validator.field) = {regex: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$|^$", length_lt: 37}]; // Vendor-specific provisioning data. Stored in Join Server. - google.protobuf.Struct provisioning_data = 46; + google.protobuf.Struct provisioning_data = 43; } message EndDevices { diff --git a/pkg/ttnpb/end_device.pb.fm.go b/pkg/ttnpb/end_device.pb.fm.go index 25e2bd92bb..71cc877753 100644 --- a/pkg/ttnpb/end_device.pb.fm.go +++ b/pkg/ttnpb/end_device.pb.fm.go @@ -299,6 +299,16 @@ func (dst *MACParameters) SetFields(src *MACParameters, paths ...string) error { var zero uint64 dst.Rx2Frequency = zero } + case "max_duty_cycle": + if len(subs) > 0 { + return fmt.Errorf("'max_duty_cycle' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.MaxDutyCycle = src.MaxDutyCycle + } else { + var zero AggregatedDutyCycle + dst.MaxDutyCycle = zero + } case "rejoin_time_periodicity": if len(subs) > 0 { return fmt.Errorf("'rejoin_time_periodicity' has no subfields, but %s were specified", subs) @@ -319,25 +329,6 @@ func (dst *MACParameters) SetFields(src *MACParameters, paths ...string) error { var zero RejoinCountExponent dst.RejoinCountPeriodicity = zero } - case "max_duty_cycle": - if len(subs) > 0 { - return fmt.Errorf("'max_duty_cycle' has no subfields, but %s were specified", subs) - } - if src != nil { - dst.MaxDutyCycle = src.MaxDutyCycle - } else { - var zero AggregatedDutyCycle - dst.MaxDutyCycle = zero - } - case "channels": - if len(subs) > 0 { - return fmt.Errorf("'channels' has no subfields, but %s were specified", subs) - } - if src != nil { - dst.Channels = src.Channels - } else { - dst.Channels = nil - } case "ping_slot_frequency": if len(subs) > 0 { return fmt.Errorf("'ping_slot_frequency' has no subfields, but %s were specified", subs) @@ -368,6 +359,15 @@ func (dst *MACParameters) SetFields(src *MACParameters, paths ...string) error { var zero uint64 dst.BeaconFrequency = zero } + case "channels": + if len(subs) > 0 { + return fmt.Errorf("'channels' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.Channels = src.Channels + } else { + dst.Channels = nil + } default: return fmt.Errorf("invalid field: '%s'", name) @@ -641,26 +641,35 @@ var EndDeviceVersionFieldPathsNested = []string{ "default_formatters.down_formatter_parameter", "default_formatters.up_formatter", "default_formatters.up_formatter_parameter", - "default_mac_parameters", - "default_mac_parameters.adr_ack_delay", - "default_mac_parameters.adr_ack_limit", - "default_mac_parameters.adr_data_rate_index", - "default_mac_parameters.adr_nb_trans", - "default_mac_parameters.adr_tx_power_index", - "default_mac_parameters.beacon_frequency", - "default_mac_parameters.channels", - "default_mac_parameters.downlink_dwell_time", - "default_mac_parameters.max_duty_cycle", - "default_mac_parameters.max_eirp", - "default_mac_parameters.ping_slot_data_rate_index", - "default_mac_parameters.ping_slot_frequency", - "default_mac_parameters.rejoin_count_periodicity", - "default_mac_parameters.rejoin_time_periodicity", - "default_mac_parameters.rx1_data_rate_offset", - "default_mac_parameters.rx1_delay", - "default_mac_parameters.rx2_data_rate_index", - "default_mac_parameters.rx2_frequency", - "default_mac_parameters.uplink_dwell_time", + "default_mac_settings", + "default_mac_settings.adr_margin", + "default_mac_settings.class_b_timeout", + "default_mac_settings.class_c_timeout", + "default_mac_settings.desired_rx1_data_rate_offset", + "default_mac_settings.desired_rx1_delay", + "default_mac_settings.desired_rx1_delay.value", + "default_mac_settings.desired_rx2_data_rate_index", + "default_mac_settings.desired_rx2_data_rate_index.value", + "default_mac_settings.desired_rx2_frequency", + "default_mac_settings.factory_preset_frequencies", + "default_mac_settings.max_duty_cycle", + "default_mac_settings.max_duty_cycle.value", + "default_mac_settings.ping_slot_data_rate_index", + "default_mac_settings.ping_slot_data_rate_index.value", + "default_mac_settings.ping_slot_frequency", + "default_mac_settings.ping_slot_periodicity", + "default_mac_settings.ping_slot_periodicity.value", + "default_mac_settings.resets_f_cnt", + "default_mac_settings.rx1_data_rate_offset", + "default_mac_settings.rx1_delay", + "default_mac_settings.rx1_delay.value", + "default_mac_settings.rx2_data_rate_index", + "default_mac_settings.rx2_data_rate_index.value", + "default_mac_settings.rx2_frequency", + "default_mac_settings.status_count_periodicity", + "default_mac_settings.status_time_periodicity", + "default_mac_settings.supports_32_bit_f_cnt", + "default_mac_settings.use_adr", "frequency_plan_id", "ids", "ids.brand_id", @@ -677,12 +686,11 @@ var EndDeviceVersionFieldPathsNested = []string{ "supports_class_b", "supports_class_c", "supports_join", - "uses_32_bit_f_cnt", } var EndDeviceVersionFieldPathsTopLevel = []string{ "default_formatters", - "default_mac_parameters", + "default_mac_settings", "frequency_plan_id", "ids", "lorawan_phy_version", @@ -695,7 +703,6 @@ var EndDeviceVersionFieldPathsTopLevel = []string{ "supports_class_b", "supports_class_c", "supports_join", - "uses_32_bit_f_cnt", } func (dst *EndDeviceVersion) SetFields(src *EndDeviceVersion, paths ...string) error { @@ -778,25 +785,25 @@ func (dst *EndDeviceVersion) SetFields(src *EndDeviceVersion, paths ...string) e var zero bool dst.SupportsClassC = zero } - case "default_mac_parameters": + case "default_mac_settings": if len(subs) > 0 { - newDst := dst.DefaultMACParameters + newDst := dst.DefaultMACSettings if newDst == nil { - newDst = &MACParameters{} - dst.DefaultMACParameters = newDst + newDst = &MACSettings{} + dst.DefaultMACSettings = newDst } - var newSrc *MACParameters + var newSrc *MACSettings if src != nil { - newSrc = src.DefaultMACParameters + newSrc = src.DefaultMACSettings } if err := newDst.SetFields(newSrc, subs...); err != nil { return err } } else { if src != nil { - dst.DefaultMACParameters = src.DefaultMACParameters + dst.DefaultMACSettings = src.DefaultMACSettings } else { - dst.DefaultMACParameters = nil + dst.DefaultMACSettings = nil } } case "min_frequency": @@ -829,16 +836,6 @@ func (dst *EndDeviceVersion) SetFields(src *EndDeviceVersion, paths ...string) e var zero bool dst.ResetsFCnt = zero } - case "uses_32_bit_f_cnt": - if len(subs) > 0 { - return fmt.Errorf("'uses_32_bit_f_cnt' has no subfields, but %s were specified", subs) - } - if src != nil { - dst.Uses32BitFCnt = src.Uses32BitFCnt - } else { - var zero bool - dst.Uses32BitFCnt = zero - } case "supports_join": if len(subs) > 0 { return fmt.Errorf("'supports_join' has no subfields, but %s were specified", subs) @@ -889,6 +886,22 @@ var MACSettingsFieldPathsNested = []string{ "adr_margin", "class_b_timeout", "class_c_timeout", + "desired_rx1_data_rate_offset", + "desired_rx1_delay", + "desired_rx1_delay.value", + "desired_rx2_data_rate_index", + "desired_rx2_data_rate_index.value", + "desired_rx2_frequency", + "factory_preset_frequencies", + "max_duty_cycle", + "max_duty_cycle.value", + "ping_slot_data_rate_index", + "ping_slot_data_rate_index.value", + "ping_slot_frequency", + "ping_slot_periodicity", + "ping_slot_periodicity.value", + "resets_f_cnt", + "rx1_data_rate_offset", "rx1_delay", "rx1_delay.value", "rx2_data_rate_index", @@ -896,6 +909,7 @@ var MACSettingsFieldPathsNested = []string{ "rx2_frequency", "status_count_periodicity", "status_time_periodicity", + "supports_32_bit_f_cnt", "use_adr", } @@ -903,43 +917,89 @@ var MACSettingsFieldPathsTopLevel = []string{ "adr_margin", "class_b_timeout", "class_c_timeout", + "desired_rx1_data_rate_offset", + "desired_rx1_delay", + "desired_rx2_data_rate_index", + "desired_rx2_frequency", + "factory_preset_frequencies", + "max_duty_cycle", + "ping_slot_data_rate_index", + "ping_slot_frequency", + "ping_slot_periodicity", + "resets_f_cnt", + "rx1_data_rate_offset", "rx1_delay", "rx2_data_rate_index", "rx2_frequency", "status_count_periodicity", "status_time_periodicity", + "supports_32_bit_f_cnt", "use_adr", } func (dst *MACSettings) SetFields(src *MACSettings, paths ...string) error { for name, subs := range _processPaths(append(paths[:0:0], paths...)) { switch name { - case "use_adr": + case "class_b_timeout": if len(subs) > 0 { - return fmt.Errorf("'use_adr' has no subfields, but %s were specified", subs) + return fmt.Errorf("'class_b_timeout' has no subfields, but %s were specified", subs) } if src != nil { - dst.UseADR = src.UseADR + dst.ClassBTimeout = src.ClassBTimeout } else { - dst.UseADR = nil + dst.ClassBTimeout = nil } - case "adr_margin": + case "ping_slot_periodicity": if len(subs) > 0 { - return fmt.Errorf("'adr_margin' has no subfields, but %s were specified", subs) + newDst := dst.PingSlotPeriodicity + if newDst == nil { + newDst = &MACSettings_PingSlotPeriodValue{} + dst.PingSlotPeriodicity = newDst + } + var newSrc *MACSettings_PingSlotPeriodValue + if src != nil { + newSrc = src.PingSlotPeriodicity + } + if err := newDst.SetFields(newSrc, subs...); err != nil { + return err + } + } else { + if src != nil { + dst.PingSlotPeriodicity = src.PingSlotPeriodicity + } else { + dst.PingSlotPeriodicity = nil + } } - if src != nil { - dst.ADRMargin = src.ADRMargin + case "ping_slot_data_rate_index": + if len(subs) > 0 { + newDst := dst.PingSlotDataRateIndex + if newDst == nil { + newDst = &MACSettings_DataRateIndexValue{} + dst.PingSlotDataRateIndex = newDst + } + var newSrc *MACSettings_DataRateIndexValue + if src != nil { + newSrc = src.PingSlotDataRateIndex + } + if err := newDst.SetFields(newSrc, subs...); err != nil { + return err + } } else { - dst.ADRMargin = nil + if src != nil { + dst.PingSlotDataRateIndex = src.PingSlotDataRateIndex + } else { + dst.PingSlotDataRateIndex = nil + } } - case "class_b_timeout": + case "ping_slot_frequency": if len(subs) > 0 { - return fmt.Errorf("'class_b_timeout' has no subfields, but %s were specified", subs) + return fmt.Errorf("'ping_slot_frequency' has no subfields, but %s were specified", subs) } if src != nil { - dst.ClassBTimeout = src.ClassBTimeout + dst.PingSlotFrequency = src.PingSlotFrequency } else { - dst.ClassBTimeout = nil + var zero uint64 + dst.PingSlotFrequency = zero } case "class_c_timeout": if len(subs) > 0 { @@ -950,6 +1010,133 @@ func (dst *MACSettings) SetFields(src *MACSettings, paths ...string) error { } else { dst.ClassCTimeout = nil } + case "rx1_delay": + if len(subs) > 0 { + newDst := dst.Rx1Delay + if newDst == nil { + newDst = &MACSettings_RxDelayValue{} + dst.Rx1Delay = newDst + } + var newSrc *MACSettings_RxDelayValue + if src != nil { + newSrc = src.Rx1Delay + } + if err := newDst.SetFields(newSrc, subs...); err != nil { + return err + } + } else { + if src != nil { + dst.Rx1Delay = src.Rx1Delay + } else { + dst.Rx1Delay = nil + } + } + case "rx1_data_rate_offset": + if len(subs) > 0 { + return fmt.Errorf("'rx1_data_rate_offset' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.Rx1DataRateOffset = src.Rx1DataRateOffset + } else { + dst.Rx1DataRateOffset = nil + } + case "rx2_data_rate_index": + if len(subs) > 0 { + newDst := dst.Rx2DataRateIndex + if newDst == nil { + newDst = &MACSettings_DataRateIndexValue{} + dst.Rx2DataRateIndex = newDst + } + var newSrc *MACSettings_DataRateIndexValue + if src != nil { + newSrc = src.Rx2DataRateIndex + } + if err := newDst.SetFields(newSrc, subs...); err != nil { + return err + } + } else { + if src != nil { + dst.Rx2DataRateIndex = src.Rx2DataRateIndex + } else { + dst.Rx2DataRateIndex = nil + } + } + case "rx2_frequency": + if len(subs) > 0 { + return fmt.Errorf("'rx2_frequency' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.Rx2Frequency = src.Rx2Frequency + } else { + var zero uint64 + dst.Rx2Frequency = zero + } + case "factory_preset_frequencies": + if len(subs) > 0 { + return fmt.Errorf("'factory_preset_frequencies' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.FactoryPresetFrequencies = src.FactoryPresetFrequencies + } else { + dst.FactoryPresetFrequencies = nil + } + case "max_duty_cycle": + if len(subs) > 0 { + newDst := dst.MaxDutyCycle + if newDst == nil { + newDst = &MACSettings_AggregatedDutyCycleValue{} + dst.MaxDutyCycle = newDst + } + var newSrc *MACSettings_AggregatedDutyCycleValue + if src != nil { + newSrc = src.MaxDutyCycle + } + if err := newDst.SetFields(newSrc, subs...); err != nil { + return err + } + } else { + if src != nil { + dst.MaxDutyCycle = src.MaxDutyCycle + } else { + dst.MaxDutyCycle = nil + } + } + case "supports_32_bit_f_cnt": + if len(subs) > 0 { + return fmt.Errorf("'supports_32_bit_f_cnt' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.Supports32BitFCnt = src.Supports32BitFCnt + } else { + dst.Supports32BitFCnt = nil + } + case "use_adr": + if len(subs) > 0 { + return fmt.Errorf("'use_adr' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.UseADR = src.UseADR + } else { + dst.UseADR = nil + } + case "adr_margin": + if len(subs) > 0 { + return fmt.Errorf("'adr_margin' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.ADRMargin = src.ADRMargin + } else { + dst.ADRMargin = nil + } + case "resets_f_cnt": + if len(subs) > 0 { + return fmt.Errorf("'resets_f_cnt' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.ResetsFCnt = src.ResetsFCnt + } else { + dst.ResetsFCnt = nil + } case "status_time_periodicity": if len(subs) > 0 { return fmt.Errorf("'status_time_periodicity' has no subfields, but %s were specified", subs) @@ -968,56 +1155,66 @@ func (dst *MACSettings) SetFields(src *MACSettings, paths ...string) error { } else { dst.StatusCountPeriodicity = nil } - case "rx1_delay": + case "desired_rx1_delay": if len(subs) > 0 { - newDst := dst.Rx1Delay + newDst := dst.DesiredRx1Delay if newDst == nil { newDst = &MACSettings_RxDelayValue{} - dst.Rx1Delay = newDst + dst.DesiredRx1Delay = newDst } var newSrc *MACSettings_RxDelayValue if src != nil { - newSrc = src.Rx1Delay + newSrc = src.DesiredRx1Delay } if err := newDst.SetFields(newSrc, subs...); err != nil { return err } } else { if src != nil { - dst.Rx1Delay = src.Rx1Delay + dst.DesiredRx1Delay = src.DesiredRx1Delay } else { - dst.Rx1Delay = nil + dst.DesiredRx1Delay = nil } } - case "rx2_data_rate_index": + case "desired_rx1_data_rate_offset": if len(subs) > 0 { - newDst := dst.Rx2DataRateIndex + return fmt.Errorf("'desired_rx1_data_rate_offset' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.DesiredRx1DataRateOffset = src.DesiredRx1DataRateOffset + } else { + dst.DesiredRx1DataRateOffset = nil + } + case "desired_rx2_data_rate_index": + if len(subs) > 0 { + newDst := dst.DesiredRx2DataRateIndex if newDst == nil { newDst = &MACSettings_DataRateIndexValue{} - dst.Rx2DataRateIndex = newDst + dst.DesiredRx2DataRateIndex = newDst } var newSrc *MACSettings_DataRateIndexValue if src != nil { - newSrc = src.Rx2DataRateIndex + newSrc = src.DesiredRx2DataRateIndex } if err := newDst.SetFields(newSrc, subs...); err != nil { return err } } else { if src != nil { - dst.Rx2DataRateIndex = src.Rx2DataRateIndex + dst.DesiredRx2DataRateIndex = src.DesiredRx2DataRateIndex } else { - dst.Rx2DataRateIndex = nil + dst.DesiredRx2DataRateIndex = nil } } - case "rx2_frequency": + case "desired_rx2_frequency": if len(subs) > 0 { - return fmt.Errorf("'rx2_frequency' has no subfields, but %s were specified", subs) + return fmt.Errorf("'desired_rx2_frequency' has no subfields, but %s were specified", subs) } if src != nil { - dst.Rx2Frequency = src.Rx2Frequency + dst.DesiredRx2Frequency = src.DesiredRx2Frequency } else { - dst.Rx2Frequency = nil + var zero uint64 + dst.DesiredRx2Frequency = zero } default: @@ -1027,15 +1224,15 @@ func (dst *MACSettings) SetFields(src *MACSettings, paths ...string) error { return nil } -var MACSettings_RxDelayValueFieldPathsNested = []string{ +var MACSettings_DataRateIndexValueFieldPathsNested = []string{ "value", } -var MACSettings_RxDelayValueFieldPathsTopLevel = []string{ +var MACSettings_DataRateIndexValueFieldPathsTopLevel = []string{ "value", } -func (dst *MACSettings_RxDelayValue) SetFields(src *MACSettings_RxDelayValue, paths ...string) error { +func (dst *MACSettings_DataRateIndexValue) SetFields(src *MACSettings_DataRateIndexValue, paths ...string) error { for name, subs := range _processPaths(append(paths[:0:0], paths...)) { switch name { case "value": @@ -1045,7 +1242,7 @@ func (dst *MACSettings_RxDelayValue) SetFields(src *MACSettings_RxDelayValue, pa if src != nil { dst.Value = src.Value } else { - var zero RxDelay + var zero DataRateIndex dst.Value = zero } @@ -1056,15 +1253,15 @@ func (dst *MACSettings_RxDelayValue) SetFields(src *MACSettings_RxDelayValue, pa return nil } -var MACSettings_DataRateIndexValueFieldPathsNested = []string{ +var MACSettings_PingSlotPeriodValueFieldPathsNested = []string{ "value", } -var MACSettings_DataRateIndexValueFieldPathsTopLevel = []string{ +var MACSettings_PingSlotPeriodValueFieldPathsTopLevel = []string{ "value", } -func (dst *MACSettings_DataRateIndexValue) SetFields(src *MACSettings_DataRateIndexValue, paths ...string) error { +func (dst *MACSettings_PingSlotPeriodValue) SetFields(src *MACSettings_PingSlotPeriodValue, paths ...string) error { for name, subs := range _processPaths(append(paths[:0:0], paths...)) { switch name { case "value": @@ -1074,7 +1271,65 @@ func (dst *MACSettings_DataRateIndexValue) SetFields(src *MACSettings_DataRateIn if src != nil { dst.Value = src.Value } else { - var zero DataRateIndex + var zero PingSlotPeriod + dst.Value = zero + } + + default: + return fmt.Errorf("invalid field: '%s'", name) + } + } + return nil +} + +var MACSettings_AggregatedDutyCycleValueFieldPathsNested = []string{ + "value", +} + +var MACSettings_AggregatedDutyCycleValueFieldPathsTopLevel = []string{ + "value", +} + +func (dst *MACSettings_AggregatedDutyCycleValue) SetFields(src *MACSettings_AggregatedDutyCycleValue, paths ...string) error { + for name, subs := range _processPaths(append(paths[:0:0], paths...)) { + switch name { + case "value": + if len(subs) > 0 { + return fmt.Errorf("'value' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.Value = src.Value + } else { + var zero AggregatedDutyCycle + dst.Value = zero + } + + default: + return fmt.Errorf("invalid field: '%s'", name) + } + } + return nil +} + +var MACSettings_RxDelayValueFieldPathsNested = []string{ + "value", +} + +var MACSettings_RxDelayValueFieldPathsTopLevel = []string{ + "value", +} + +func (dst *MACSettings_RxDelayValue) SetFields(src *MACSettings_RxDelayValue, paths ...string) error { + for name, subs := range _processPaths(append(paths[:0:0], paths...)) { + switch name { + case "value": + if len(subs) > 0 { + return fmt.Errorf("'value' has no subfields, but %s were specified", subs) + } + if src != nil { + dst.Value = src.Value + } else { + var zero RxDelay dst.Value = zero } @@ -1630,26 +1885,6 @@ var EndDeviceFieldPathsNested = []string{ "attributes", "battery_percentage", "created_at", - "default_mac_parameters", - "default_mac_parameters.adr_ack_delay", - "default_mac_parameters.adr_ack_limit", - "default_mac_parameters.adr_data_rate_index", - "default_mac_parameters.adr_nb_trans", - "default_mac_parameters.adr_tx_power_index", - "default_mac_parameters.beacon_frequency", - "default_mac_parameters.channels", - "default_mac_parameters.downlink_dwell_time", - "default_mac_parameters.max_duty_cycle", - "default_mac_parameters.max_eirp", - "default_mac_parameters.ping_slot_data_rate_index", - "default_mac_parameters.ping_slot_frequency", - "default_mac_parameters.rejoin_count_periodicity", - "default_mac_parameters.rejoin_time_periodicity", - "default_mac_parameters.rx1_data_rate_offset", - "default_mac_parameters.rx1_delay", - "default_mac_parameters.rx2_data_rate_index", - "default_mac_parameters.rx2_frequency", - "default_mac_parameters.uplink_dwell_time", "description", "downlink_margin", "formatters", @@ -1678,6 +1913,22 @@ var EndDeviceFieldPathsNested = []string{ "mac_settings.adr_margin", "mac_settings.class_b_timeout", "mac_settings.class_c_timeout", + "mac_settings.desired_rx1_data_rate_offset", + "mac_settings.desired_rx1_delay", + "mac_settings.desired_rx1_delay.value", + "mac_settings.desired_rx2_data_rate_index", + "mac_settings.desired_rx2_data_rate_index.value", + "mac_settings.desired_rx2_frequency", + "mac_settings.factory_preset_frequencies", + "mac_settings.max_duty_cycle", + "mac_settings.max_duty_cycle.value", + "mac_settings.ping_slot_data_rate_index", + "mac_settings.ping_slot_data_rate_index.value", + "mac_settings.ping_slot_frequency", + "mac_settings.ping_slot_periodicity", + "mac_settings.ping_slot_periodicity.value", + "mac_settings.resets_f_cnt", + "mac_settings.rx1_data_rate_offset", "mac_settings.rx1_delay", "mac_settings.rx1_delay.value", "mac_settings.rx2_data_rate_index", @@ -1685,6 +1936,7 @@ var EndDeviceFieldPathsNested = []string{ "mac_settings.rx2_frequency", "mac_settings.status_count_periodicity", "mac_settings.status_time_periodicity", + "mac_settings.supports_32_bit_f_cnt", "mac_settings.use_adr", "mac_state", "mac_state.current_parameters", @@ -1914,7 +2166,6 @@ var EndDeviceFieldPathsNested = []string{ "recent_adr_uplinks", "recent_downlinks", "recent_uplinks", - "resets_f_cnt", "resets_join_nonces", "root_keys", "root_keys.app_key", @@ -1951,7 +2202,6 @@ var EndDeviceFieldPathsNested = []string{ "supports_join", "updated_at", "used_dev_nonces", - "uses_32_bit_f_cnt", "version_ids", "version_ids.brand_id", "version_ids.firmware_version", @@ -1964,7 +2214,6 @@ var EndDeviceFieldPathsTopLevel = []string{ "attributes", "battery_percentage", "created_at", - "default_mac_parameters", "description", "downlink_margin", "formatters", @@ -1994,7 +2243,6 @@ var EndDeviceFieldPathsTopLevel = []string{ "recent_adr_uplinks", "recent_downlinks", "recent_uplinks", - "resets_f_cnt", "resets_join_nonces", "root_keys", "service_profile_id", @@ -2004,7 +2252,6 @@ var EndDeviceFieldPathsTopLevel = []string{ "supports_join", "updated_at", "used_dev_nonces", - "uses_32_bit_f_cnt", "version_ids", } @@ -2198,27 +2445,6 @@ func (dst *EndDevice) SetFields(src *EndDevice, paths ...string) error { var zero string dst.FrequencyPlanID = zero } - case "default_mac_parameters": - if len(subs) > 0 { - newDst := dst.DefaultMACParameters - if newDst == nil { - newDst = &MACParameters{} - dst.DefaultMACParameters = newDst - } - var newSrc *MACParameters - if src != nil { - newSrc = src.DefaultMACParameters - } - if err := newDst.SetFields(newSrc, subs...); err != nil { - return err - } - } else { - if src != nil { - dst.DefaultMACParameters = src.DefaultMACParameters - } else { - dst.DefaultMACParameters = nil - } - } case "min_frequency": if len(subs) > 0 { return fmt.Errorf("'min_frequency' has no subfields, but %s were specified", subs) @@ -2239,26 +2465,6 @@ func (dst *EndDevice) SetFields(src *EndDevice, paths ...string) error { var zero uint64 dst.MaxFrequency = zero } - case "resets_f_cnt": - if len(subs) > 0 { - return fmt.Errorf("'resets_f_cnt' has no subfields, but %s were specified", subs) - } - if src != nil { - dst.ResetsFCnt = src.ResetsFCnt - } else { - var zero bool - dst.ResetsFCnt = zero - } - case "uses_32_bit_f_cnt": - if len(subs) > 0 { - return fmt.Errorf("'uses_32_bit_f_cnt' has no subfields, but %s were specified", subs) - } - if src != nil { - dst.Uses32BitFCnt = src.Uses32BitFCnt - } else { - var zero bool - dst.Uses32BitFCnt = zero - } case "supports_join": if len(subs) > 0 { return fmt.Errorf("'supports_join' has no subfields, but %s were specified", subs) @@ -2599,26 +2805,6 @@ var CreateEndDeviceRequestFieldPathsNested = []string{ "end_device.attributes", "end_device.battery_percentage", "end_device.created_at", - "end_device.default_mac_parameters", - "end_device.default_mac_parameters.adr_ack_delay", - "end_device.default_mac_parameters.adr_ack_limit", - "end_device.default_mac_parameters.adr_data_rate_index", - "end_device.default_mac_parameters.adr_nb_trans", - "end_device.default_mac_parameters.adr_tx_power_index", - "end_device.default_mac_parameters.beacon_frequency", - "end_device.default_mac_parameters.channels", - "end_device.default_mac_parameters.downlink_dwell_time", - "end_device.default_mac_parameters.max_duty_cycle", - "end_device.default_mac_parameters.max_eirp", - "end_device.default_mac_parameters.ping_slot_data_rate_index", - "end_device.default_mac_parameters.ping_slot_frequency", - "end_device.default_mac_parameters.rejoin_count_periodicity", - "end_device.default_mac_parameters.rejoin_time_periodicity", - "end_device.default_mac_parameters.rx1_data_rate_offset", - "end_device.default_mac_parameters.rx1_delay", - "end_device.default_mac_parameters.rx2_data_rate_index", - "end_device.default_mac_parameters.rx2_frequency", - "end_device.default_mac_parameters.uplink_dwell_time", "end_device.description", "end_device.downlink_margin", "end_device.formatters", @@ -2647,6 +2833,22 @@ var CreateEndDeviceRequestFieldPathsNested = []string{ "end_device.mac_settings.adr_margin", "end_device.mac_settings.class_b_timeout", "end_device.mac_settings.class_c_timeout", + "end_device.mac_settings.desired_rx1_data_rate_offset", + "end_device.mac_settings.desired_rx1_delay", + "end_device.mac_settings.desired_rx1_delay.value", + "end_device.mac_settings.desired_rx2_data_rate_index", + "end_device.mac_settings.desired_rx2_data_rate_index.value", + "end_device.mac_settings.desired_rx2_frequency", + "end_device.mac_settings.factory_preset_frequencies", + "end_device.mac_settings.max_duty_cycle", + "end_device.mac_settings.max_duty_cycle.value", + "end_device.mac_settings.ping_slot_data_rate_index", + "end_device.mac_settings.ping_slot_data_rate_index.value", + "end_device.mac_settings.ping_slot_frequency", + "end_device.mac_settings.ping_slot_periodicity", + "end_device.mac_settings.ping_slot_periodicity.value", + "end_device.mac_settings.resets_f_cnt", + "end_device.mac_settings.rx1_data_rate_offset", "end_device.mac_settings.rx1_delay", "end_device.mac_settings.rx1_delay.value", "end_device.mac_settings.rx2_data_rate_index", @@ -2654,6 +2856,7 @@ var CreateEndDeviceRequestFieldPathsNested = []string{ "end_device.mac_settings.rx2_frequency", "end_device.mac_settings.status_count_periodicity", "end_device.mac_settings.status_time_periodicity", + "end_device.mac_settings.supports_32_bit_f_cnt", "end_device.mac_settings.use_adr", "end_device.mac_state", "end_device.mac_state.current_parameters", @@ -2883,7 +3086,6 @@ var CreateEndDeviceRequestFieldPathsNested = []string{ "end_device.recent_adr_uplinks", "end_device.recent_downlinks", "end_device.recent_uplinks", - "end_device.resets_f_cnt", "end_device.resets_join_nonces", "end_device.root_keys", "end_device.root_keys.app_key", @@ -2920,7 +3122,6 @@ var CreateEndDeviceRequestFieldPathsNested = []string{ "end_device.supports_join", "end_device.updated_at", "end_device.used_dev_nonces", - "end_device.uses_32_bit_f_cnt", "end_device.version_ids", "end_device.version_ids.brand_id", "end_device.version_ids.firmware_version", @@ -2967,26 +3168,6 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{ "end_device.attributes", "end_device.battery_percentage", "end_device.created_at", - "end_device.default_mac_parameters", - "end_device.default_mac_parameters.adr_ack_delay", - "end_device.default_mac_parameters.adr_ack_limit", - "end_device.default_mac_parameters.adr_data_rate_index", - "end_device.default_mac_parameters.adr_nb_trans", - "end_device.default_mac_parameters.adr_tx_power_index", - "end_device.default_mac_parameters.beacon_frequency", - "end_device.default_mac_parameters.channels", - "end_device.default_mac_parameters.downlink_dwell_time", - "end_device.default_mac_parameters.max_duty_cycle", - "end_device.default_mac_parameters.max_eirp", - "end_device.default_mac_parameters.ping_slot_data_rate_index", - "end_device.default_mac_parameters.ping_slot_frequency", - "end_device.default_mac_parameters.rejoin_count_periodicity", - "end_device.default_mac_parameters.rejoin_time_periodicity", - "end_device.default_mac_parameters.rx1_data_rate_offset", - "end_device.default_mac_parameters.rx1_delay", - "end_device.default_mac_parameters.rx2_data_rate_index", - "end_device.default_mac_parameters.rx2_frequency", - "end_device.default_mac_parameters.uplink_dwell_time", "end_device.description", "end_device.downlink_margin", "end_device.formatters", @@ -3015,6 +3196,22 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{ "end_device.mac_settings.adr_margin", "end_device.mac_settings.class_b_timeout", "end_device.mac_settings.class_c_timeout", + "end_device.mac_settings.desired_rx1_data_rate_offset", + "end_device.mac_settings.desired_rx1_delay", + "end_device.mac_settings.desired_rx1_delay.value", + "end_device.mac_settings.desired_rx2_data_rate_index", + "end_device.mac_settings.desired_rx2_data_rate_index.value", + "end_device.mac_settings.desired_rx2_frequency", + "end_device.mac_settings.factory_preset_frequencies", + "end_device.mac_settings.max_duty_cycle", + "end_device.mac_settings.max_duty_cycle.value", + "end_device.mac_settings.ping_slot_data_rate_index", + "end_device.mac_settings.ping_slot_data_rate_index.value", + "end_device.mac_settings.ping_slot_frequency", + "end_device.mac_settings.ping_slot_periodicity", + "end_device.mac_settings.ping_slot_periodicity.value", + "end_device.mac_settings.resets_f_cnt", + "end_device.mac_settings.rx1_data_rate_offset", "end_device.mac_settings.rx1_delay", "end_device.mac_settings.rx1_delay.value", "end_device.mac_settings.rx2_data_rate_index", @@ -3022,6 +3219,7 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{ "end_device.mac_settings.rx2_frequency", "end_device.mac_settings.status_count_periodicity", "end_device.mac_settings.status_time_periodicity", + "end_device.mac_settings.supports_32_bit_f_cnt", "end_device.mac_settings.use_adr", "end_device.mac_state", "end_device.mac_state.current_parameters", @@ -3251,7 +3449,6 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{ "end_device.recent_adr_uplinks", "end_device.recent_downlinks", "end_device.recent_uplinks", - "end_device.resets_f_cnt", "end_device.resets_join_nonces", "end_device.root_keys", "end_device.root_keys.app_key", @@ -3288,7 +3485,6 @@ var UpdateEndDeviceRequestFieldPathsNested = []string{ "end_device.supports_join", "end_device.updated_at", "end_device.used_dev_nonces", - "end_device.uses_32_bit_f_cnt", "end_device.version_ids", "end_device.version_ids.brand_id", "end_device.version_ids.firmware_version", @@ -3488,26 +3684,6 @@ var SetEndDeviceRequestFieldPathsNested = []string{ "device.attributes", "device.battery_percentage", "device.created_at", - "device.default_mac_parameters", - "device.default_mac_parameters.adr_ack_delay", - "device.default_mac_parameters.adr_ack_limit", - "device.default_mac_parameters.adr_data_rate_index", - "device.default_mac_parameters.adr_nb_trans", - "device.default_mac_parameters.adr_tx_power_index", - "device.default_mac_parameters.beacon_frequency", - "device.default_mac_parameters.channels", - "device.default_mac_parameters.downlink_dwell_time", - "device.default_mac_parameters.max_duty_cycle", - "device.default_mac_parameters.max_eirp", - "device.default_mac_parameters.ping_slot_data_rate_index", - "device.default_mac_parameters.ping_slot_frequency", - "device.default_mac_parameters.rejoin_count_periodicity", - "device.default_mac_parameters.rejoin_time_periodicity", - "device.default_mac_parameters.rx1_data_rate_offset", - "device.default_mac_parameters.rx1_delay", - "device.default_mac_parameters.rx2_data_rate_index", - "device.default_mac_parameters.rx2_frequency", - "device.default_mac_parameters.uplink_dwell_time", "device.description", "device.downlink_margin", "device.formatters", @@ -3536,6 +3712,22 @@ var SetEndDeviceRequestFieldPathsNested = []string{ "device.mac_settings.adr_margin", "device.mac_settings.class_b_timeout", "device.mac_settings.class_c_timeout", + "device.mac_settings.desired_rx1_data_rate_offset", + "device.mac_settings.desired_rx1_delay", + "device.mac_settings.desired_rx1_delay.value", + "device.mac_settings.desired_rx2_data_rate_index", + "device.mac_settings.desired_rx2_data_rate_index.value", + "device.mac_settings.desired_rx2_frequency", + "device.mac_settings.factory_preset_frequencies", + "device.mac_settings.max_duty_cycle", + "device.mac_settings.max_duty_cycle.value", + "device.mac_settings.ping_slot_data_rate_index", + "device.mac_settings.ping_slot_data_rate_index.value", + "device.mac_settings.ping_slot_frequency", + "device.mac_settings.ping_slot_periodicity", + "device.mac_settings.ping_slot_periodicity.value", + "device.mac_settings.resets_f_cnt", + "device.mac_settings.rx1_data_rate_offset", "device.mac_settings.rx1_delay", "device.mac_settings.rx1_delay.value", "device.mac_settings.rx2_data_rate_index", @@ -3543,6 +3735,7 @@ var SetEndDeviceRequestFieldPathsNested = []string{ "device.mac_settings.rx2_frequency", "device.mac_settings.status_count_periodicity", "device.mac_settings.status_time_periodicity", + "device.mac_settings.supports_32_bit_f_cnt", "device.mac_settings.use_adr", "device.mac_state", "device.mac_state.current_parameters", @@ -3772,7 +3965,6 @@ var SetEndDeviceRequestFieldPathsNested = []string{ "device.recent_adr_uplinks", "device.recent_downlinks", "device.recent_uplinks", - "device.resets_f_cnt", "device.resets_join_nonces", "device.root_keys", "device.root_keys.app_key", @@ -3809,7 +4001,6 @@ var SetEndDeviceRequestFieldPathsNested = []string{ "device.supports_join", "device.updated_at", "device.used_dev_nonces", - "device.uses_32_bit_f_cnt", "device.version_ids", "device.version_ids.brand_id", "device.version_ids.firmware_version", diff --git a/pkg/ttnpb/end_device.pb.go b/pkg/ttnpb/end_device.pb.go index 75ced02f13..a5c4aa0481 100644 --- a/pkg/ttnpb/end_device.pb.go +++ b/pkg/ttnpb/end_device.pb.go @@ -62,7 +62,7 @@ var PowerState_value = map[string]int32{ } func (PowerState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{0} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{0} } type Session struct { @@ -87,7 +87,7 @@ type Session struct { func (m *Session) Reset() { *m = Session{} } func (*Session) ProtoMessage() {} func (*Session) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{0} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{0} } func (m *Session) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -178,28 +178,28 @@ type MACParameters struct { Rx2DataRateIndex DataRateIndex `protobuf:"varint,11,opt,name=rx2_data_rate_index,json=rx2DataRateIndex,proto3,enum=ttn.lorawan.v3.DataRateIndex" json:"rx2_data_rate_index,omitempty"` // Frequency for Rx2 (Hz). Rx2Frequency uint64 `protobuf:"varint,12,opt,name=rx2_frequency,json=rx2Frequency,proto3" json:"rx2_frequency,omitempty"` + // Maximum uplink duty cycle (of all channels). + MaxDutyCycle AggregatedDutyCycle `protobuf:"varint,13,opt,name=max_duty_cycle,json=maxDutyCycle,proto3,enum=ttn.lorawan.v3.AggregatedDutyCycle" json:"max_duty_cycle,omitempty"` // Time within which a rejoin-request must be sent. - RejoinTimePeriodicity RejoinTimeExponent `protobuf:"varint,13,opt,name=rejoin_time_periodicity,json=rejoinTimePeriodicity,proto3,enum=ttn.lorawan.v3.RejoinTimeExponent" json:"rejoin_time_periodicity,omitempty"` + RejoinTimePeriodicity RejoinTimeExponent `protobuf:"varint,14,opt,name=rejoin_time_periodicity,json=rejoinTimePeriodicity,proto3,enum=ttn.lorawan.v3.RejoinTimeExponent" json:"rejoin_time_periodicity,omitempty"` // Message count within which a rejoin-request must be sent. - RejoinCountPeriodicity RejoinCountExponent `protobuf:"varint,14,opt,name=rejoin_count_periodicity,json=rejoinCountPeriodicity,proto3,enum=ttn.lorawan.v3.RejoinCountExponent" json:"rejoin_count_periodicity,omitempty"` - // Maximum uplink duty cycle (of all channels). - MaxDutyCycle AggregatedDutyCycle `protobuf:"varint,15,opt,name=max_duty_cycle,json=maxDutyCycle,proto3,enum=ttn.lorawan.v3.AggregatedDutyCycle" json:"max_duty_cycle,omitempty"` - // Configured uplink channels and optionally Rx1 frequency. - Channels []*MACParameters_Channel `protobuf:"bytes,16,rep,name=channels,proto3" json:"channels,omitempty"` + RejoinCountPeriodicity RejoinCountExponent `protobuf:"varint,15,opt,name=rejoin_count_periodicity,json=rejoinCountPeriodicity,proto3,enum=ttn.lorawan.v3.RejoinCountExponent" json:"rejoin_count_periodicity,omitempty"` // Frequency of the class B ping slot (Hz). - PingSlotFrequency uint64 `protobuf:"varint,17,opt,name=ping_slot_frequency,json=pingSlotFrequency,proto3" json:"ping_slot_frequency,omitempty"` + PingSlotFrequency uint64 `protobuf:"varint,16,opt,name=ping_slot_frequency,json=pingSlotFrequency,proto3" json:"ping_slot_frequency,omitempty"` // Data rate index of the class B ping slot. - PingSlotDataRateIndex DataRateIndex `protobuf:"varint,18,opt,name=ping_slot_data_rate_index,json=pingSlotDataRateIndex,proto3,enum=ttn.lorawan.v3.DataRateIndex" json:"ping_slot_data_rate_index,omitempty"` + PingSlotDataRateIndex DataRateIndex `protobuf:"varint,17,opt,name=ping_slot_data_rate_index,json=pingSlotDataRateIndex,proto3,enum=ttn.lorawan.v3.DataRateIndex" json:"ping_slot_data_rate_index,omitempty"` // Frequency of the class B beacon (Hz). - BeaconFrequency uint64 `protobuf:"varint,19,opt,name=beacon_frequency,json=beaconFrequency,proto3" json:"beacon_frequency,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_sizecache int32 `json:"-"` + BeaconFrequency uint64 `protobuf:"varint,18,opt,name=beacon_frequency,json=beaconFrequency,proto3" json:"beacon_frequency,omitempty"` + // Configured uplink channels and optionally Rx1 frequency. + Channels []*MACParameters_Channel `protobuf:"bytes,19,rep,name=channels,proto3" json:"channels,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *MACParameters) Reset() { *m = MACParameters{} } func (*MACParameters) ProtoMessage() {} func (*MACParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{1} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{1} } func (m *MACParameters) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -312,6 +312,13 @@ func (m *MACParameters) GetRx2Frequency() uint64 { return 0 } +func (m *MACParameters) GetMaxDutyCycle() AggregatedDutyCycle { + if m != nil { + return m.MaxDutyCycle + } + return DUTY_CYCLE_1 +} + func (m *MACParameters) GetRejoinTimePeriodicity() RejoinTimeExponent { if m != nil { return m.RejoinTimePeriodicity @@ -326,20 +333,6 @@ func (m *MACParameters) GetRejoinCountPeriodicity() RejoinCountExponent { return REJOIN_COUNT_16 } -func (m *MACParameters) GetMaxDutyCycle() AggregatedDutyCycle { - if m != nil { - return m.MaxDutyCycle - } - return DUTY_CYCLE_1 -} - -func (m *MACParameters) GetChannels() []*MACParameters_Channel { - if m != nil { - return m.Channels - } - return nil -} - func (m *MACParameters) GetPingSlotFrequency() uint64 { if m != nil { return m.PingSlotFrequency @@ -361,6 +354,13 @@ func (m *MACParameters) GetBeaconFrequency() uint64 { return 0 } +func (m *MACParameters) GetChannels() []*MACParameters_Channel { + if m != nil { + return m.Channels + } + return nil +} + type MACParameters_Channel struct { // Uplink frequency of the channel (Hz). UplinkFrequency uint64 `protobuf:"varint,1,opt,name=uplink_frequency,json=uplinkFrequency,proto3" json:"uplink_frequency,omitempty"` @@ -379,7 +379,7 @@ type MACParameters_Channel struct { func (m *MACParameters_Channel) Reset() { *m = MACParameters_Channel{} } func (*MACParameters_Channel) ProtoMessage() {} func (*MACParameters_Channel) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{1, 0} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{1, 0} } func (m *MACParameters_Channel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -456,7 +456,7 @@ type EndDeviceBrand struct { func (m *EndDeviceBrand) Reset() { *m = EndDeviceBrand{} } func (*EndDeviceBrand) ProtoMessage() {} func (*EndDeviceBrand) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{2} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{2} } func (m *EndDeviceBrand) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -524,7 +524,7 @@ type EndDeviceModel struct { func (m *EndDeviceModel) Reset() { *m = EndDeviceModel{} } func (*EndDeviceModel) ProtoMessage() {} func (*EndDeviceModel) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{3} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{3} } func (m *EndDeviceModel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -587,7 +587,7 @@ type EndDeviceVersionIdentifiers struct { func (m *EndDeviceVersionIdentifiers) Reset() { *m = EndDeviceVersionIdentifiers{} } func (*EndDeviceVersionIdentifiers) ProtoMessage() {} func (*EndDeviceVersionIdentifiers) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{4} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{4} } func (m *EndDeviceVersionIdentifiers) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -660,16 +660,14 @@ type EndDeviceVersion struct { SupportsClassB bool `protobuf:"varint,6,opt,name=supports_class_b,json=supportsClassB,proto3" json:"supports_class_b,omitempty"` // Whether the device supports class C. SupportsClassC bool `protobuf:"varint,7,opt,name=supports_class_c,json=supportsClassC,proto3" json:"supports_class_c,omitempty"` - // Default MAC layer parameters, to which device is reset by default (e.g. on join or ResetInd). - DefaultMACParameters *MACParameters `protobuf:"bytes,8,opt,name=default_mac_parameters,json=defaultMacParameters,proto3" json:"default_mac_parameters,omitempty"` + // Default MAC layer settings of the device. + DefaultMACSettings *MACSettings `protobuf:"bytes,8,opt,name=default_mac_settings,json=defaultMacSettings,proto3" json:"default_mac_settings,omitempty"` // Minimum frequency the device is capable of using (Hz). MinFrequency uint64 `protobuf:"varint,9,opt,name=min_frequency,json=minFrequency,proto3" json:"min_frequency,omitempty"` // Maximum frequency the device is capable of using (Hz). MaxFrequency uint64 `protobuf:"varint,10,opt,name=max_frequency,json=maxFrequency,proto3" json:"max_frequency,omitempty"` // Whether the device resets the frame counters (not LoRaWAN compliant). ResetsFCnt bool `protobuf:"varint,11,opt,name=resets_f_cnt,json=resetsFCnt,proto3" json:"resets_f_cnt,omitempty"` - // Whether the device uses 32-bit frame counters. - Uses32BitFCnt bool `protobuf:"varint,12,opt,name=uses_32_bit_f_cnt,json=uses32BitFCnt,proto3" json:"uses_32_bit_f_cnt,omitempty"` // The device supports join (it's OTAA). SupportsJoin bool `protobuf:"varint,13,opt,name=supports_join,json=supportsJoin,proto3" json:"supports_join,omitempty"` // Whether the device resets the join and dev nonces (not LoRaWAN 1.1 compliant). @@ -683,7 +681,7 @@ type EndDeviceVersion struct { func (m *EndDeviceVersion) Reset() { *m = EndDeviceVersion{} } func (*EndDeviceVersion) ProtoMessage() {} func (*EndDeviceVersion) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{5} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{5} } func (m *EndDeviceVersion) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -754,9 +752,9 @@ func (m *EndDeviceVersion) GetSupportsClassC() bool { return false } -func (m *EndDeviceVersion) GetDefaultMACParameters() *MACParameters { +func (m *EndDeviceVersion) GetDefaultMACSettings() *MACSettings { if m != nil { - return m.DefaultMACParameters + return m.DefaultMACSettings } return nil } @@ -782,13 +780,6 @@ func (m *EndDeviceVersion) GetResetsFCnt() bool { return false } -func (m *EndDeviceVersion) GetUses32BitFCnt() bool { - if m != nil { - return m.Uses32BitFCnt - } - return false -} - func (m *EndDeviceVersion) GetSupportsJoin() bool { if m != nil { return m.SupportsJoin @@ -811,29 +802,68 @@ func (m *EndDeviceVersion) GetDefaultFormatters() MessagePayloadFormatters { } type MACSettings struct { - UseADR *types.BoolValue `protobuf:"bytes,1,opt,name=use_adr,json=useAdr,proto3" json:"use_adr,omitempty"` + // Maximum delay for the device to answer a MAC request or a confirmed downlink frame. + // Must be set if the device supports class B. + ClassBTimeout *time.Duration `protobuf:"bytes,1,opt,name=class_b_timeout,json=classBTimeout,proto3,stdduration" json:"class_b_timeout,omitempty"` + // Periodicity of the class B ping slot. + // Must be set if the device supports class B. + PingSlotPeriodicity *MACSettings_PingSlotPeriodValue `protobuf:"bytes,2,opt,name=ping_slot_periodicity,json=pingSlotPeriodicity,proto3" json:"ping_slot_periodicity,omitempty"` + // Data rate index of the class B ping slot. + // Must be set if the device supports class B. + PingSlotDataRateIndex *MACSettings_DataRateIndexValue `protobuf:"bytes,3,opt,name=ping_slot_data_rate_index,json=pingSlotDataRateIndex,proto3" json:"ping_slot_data_rate_index,omitempty"` + // Frequency of the class B ping slot (Hz). + // Must be set if the device supports class B. + PingSlotFrequency uint64 `protobuf:"varint,4,opt,name=ping_slot_frequency,json=pingSlotFrequency,proto3" json:"ping_slot_frequency,omitempty"` + // Maximum delay for the device to answer a MAC request or a confirmed downlink frame. + // Must be set if the device supports class C. + ClassCTimeout *time.Duration `protobuf:"bytes,5,opt,name=class_c_timeout,json=classCTimeout,proto3,stdduration" json:"class_c_timeout,omitempty"` + // Class A Rx1 delay. + // Must be set if the device is ABP. + Rx1Delay *MACSettings_RxDelayValue `protobuf:"bytes,6,opt,name=rx1_delay,json=rx1Delay,proto3" json:"rx1_delay,omitempty"` + // Rx1 data rate offset. + // Must be set if the device is ABP. + Rx1DataRateOffset *types.UInt32Value `protobuf:"bytes,7,opt,name=rx1_data_rate_offset,json=rx1DataRateOffset,proto3" json:"rx1_data_rate_offset,omitempty"` + // Data rate index for Rx2. + // Must be set if the device is ABP. + Rx2DataRateIndex *MACSettings_DataRateIndexValue `protobuf:"bytes,8,opt,name=rx2_data_rate_index,json=rx2DataRateIndex,proto3" json:"rx2_data_rate_index,omitempty"` + // Frequency for Rx2 (Hz). + // Must be set if the device is ABP. + Rx2Frequency uint64 `protobuf:"varint,9,opt,name=rx2_frequency,json=rx2Frequency,proto3" json:"rx2_frequency,omitempty"` + // List of factory-preset frequencies. + // Must be set if the device is ABP. + FactoryPresetFrequencies []uint64 `protobuf:"varint,10,rep,packed,name=factory_preset_frequencies,json=factoryPresetFrequencies,proto3" json:"factory_preset_frequencies,omitempty"` + // Maximum uplink duty cycle (of all channels). + MaxDutyCycle *MACSettings_AggregatedDutyCycleValue `protobuf:"bytes,11,opt,name=max_duty_cycle,json=maxDutyCycle,proto3" json:"max_duty_cycle,omitempty"` + // Whether the device supports 32-bit frame counters. + // Must be set if the device MAC version is 1.0. + Supports32BitFCnt *types.BoolValue `protobuf:"bytes,12,opt,name=supports_32_bit_f_cnt,json=supports32BitFCnt,proto3" json:"supports_32_bit_f_cnt,omitempty"` + // Whether the Network Server should use ADR for the device. + UseADR *types.BoolValue `protobuf:"bytes,13,opt,name=use_adr,json=useAdr,proto3" json:"use_adr,omitempty"` // The ADR margin tells the network server how much margin it should add in ADR requests. // A bigger margin is less efficient, but gives a better chance of successful reception. - ADRMargin *types.FloatValue `protobuf:"bytes,2,opt,name=adr_margin,json=adrMargin,proto3" json:"adr_margin,omitempty"` - // Deadline for the device to respond to requests from the Network Server. - ClassBTimeout *time.Duration `protobuf:"bytes,3,opt,name=class_b_timeout,json=classBTimeout,proto3,stdduration" json:"class_b_timeout,omitempty"` - // Deadline for the device to respond to requests from the Network Server. - ClassCTimeout *time.Duration `protobuf:"bytes,4,opt,name=class_c_timeout,json=classCTimeout,proto3,stdduration" json:"class_c_timeout,omitempty"` + ADRMargin *types.FloatValue `protobuf:"bytes,14,opt,name=adr_margin,json=adrMargin,proto3" json:"adr_margin,omitempty"` + // Whether the device resets the frame counters (not LoRaWAN compliant). + ResetsFCnt *types.BoolValue `protobuf:"bytes,15,opt,name=resets_f_cnt,json=resetsFCnt,proto3" json:"resets_f_cnt,omitempty"` // The interval after which a DevStatusReq MACCommand shall be sent. - StatusTimePeriodicity *time.Duration `protobuf:"bytes,5,opt,name=status_time_periodicity,json=statusTimePeriodicity,proto3,stdduration" json:"status_time_periodicity,omitempty"` + StatusTimePeriodicity *time.Duration `protobuf:"bytes,16,opt,name=status_time_periodicity,json=statusTimePeriodicity,proto3,stdduration" json:"status_time_periodicity,omitempty"` // Number of uplink messages after which a DevStatusReq MACCommand shall be sent. - StatusCountPeriodicity *types.UInt32Value `protobuf:"bytes,6,opt,name=status_count_periodicity,json=statusCountPeriodicity,proto3" json:"status_count_periodicity,omitempty"` - Rx1Delay *MACSettings_RxDelayValue `protobuf:"bytes,7,opt,name=rx1_delay,json=rx1Delay,proto3" json:"rx1_delay,omitempty"` - Rx2DataRateIndex *MACSettings_DataRateIndexValue `protobuf:"bytes,8,opt,name=rx2_data_rate_index,json=rx2DataRateIndex,proto3" json:"rx2_data_rate_index,omitempty"` - Rx2Frequency *types.UInt64Value `protobuf:"bytes,9,opt,name=rx2_frequency,json=rx2Frequency,proto3" json:"rx2_frequency,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_sizecache int32 `json:"-"` + StatusCountPeriodicity *types.UInt32Value `protobuf:"bytes,17,opt,name=status_count_periodicity,json=statusCountPeriodicity,proto3" json:"status_count_periodicity,omitempty"` + // The Rx1 delay Network Server should configure device to use via MAC commands or Join-Accept. + DesiredRx1Delay *MACSettings_RxDelayValue `protobuf:"bytes,18,opt,name=desired_rx1_delay,json=desiredRx1Delay,proto3" json:"desired_rx1_delay,omitempty"` + // The Rx1 data rate offset Network Server should configure device to use via MAC commands or Join-Accept. + DesiredRx1DataRateOffset *types.UInt32Value `protobuf:"bytes,19,opt,name=desired_rx1_data_rate_offset,json=desiredRx1DataRateOffset,proto3" json:"desired_rx1_data_rate_offset,omitempty"` + // The Rx2 data rate index Network Server should configure device to use via MAC commands or Join-Accept. + DesiredRx2DataRateIndex *MACSettings_DataRateIndexValue `protobuf:"bytes,20,opt,name=desired_rx2_data_rate_index,json=desiredRx2DataRateIndex,proto3" json:"desired_rx2_data_rate_index,omitempty"` + // The Rx2 frequency index Network Server should configure device to use via MAC commands. + DesiredRx2Frequency uint64 `protobuf:"varint,21,opt,name=desired_rx2_frequency,json=desiredRx2Frequency,proto3" json:"desired_rx2_frequency,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *MACSettings) Reset() { *m = MACSettings{} } func (*MACSettings) ProtoMessage() {} func (*MACSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{6} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{6} } func (m *MACSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -862,51 +892,51 @@ func (m *MACSettings) XXX_DiscardUnknown() { var xxx_messageInfo_MACSettings proto.InternalMessageInfo -func (m *MACSettings) GetUseADR() *types.BoolValue { +func (m *MACSettings) GetClassBTimeout() *time.Duration { if m != nil { - return m.UseADR + return m.ClassBTimeout } return nil } -func (m *MACSettings) GetADRMargin() *types.FloatValue { +func (m *MACSettings) GetPingSlotPeriodicity() *MACSettings_PingSlotPeriodValue { if m != nil { - return m.ADRMargin + return m.PingSlotPeriodicity } return nil } -func (m *MACSettings) GetClassBTimeout() *time.Duration { +func (m *MACSettings) GetPingSlotDataRateIndex() *MACSettings_DataRateIndexValue { if m != nil { - return m.ClassBTimeout + return m.PingSlotDataRateIndex } return nil } -func (m *MACSettings) GetClassCTimeout() *time.Duration { +func (m *MACSettings) GetPingSlotFrequency() uint64 { if m != nil { - return m.ClassCTimeout + return m.PingSlotFrequency } - return nil + return 0 } -func (m *MACSettings) GetStatusTimePeriodicity() *time.Duration { +func (m *MACSettings) GetClassCTimeout() *time.Duration { if m != nil { - return m.StatusTimePeriodicity + return m.ClassCTimeout } return nil } -func (m *MACSettings) GetStatusCountPeriodicity() *types.UInt32Value { +func (m *MACSettings) GetRx1Delay() *MACSettings_RxDelayValue { if m != nil { - return m.StatusCountPeriodicity + return m.Rx1Delay } return nil } -func (m *MACSettings) GetRx1Delay() *MACSettings_RxDelayValue { +func (m *MACSettings) GetRx1DataRateOffset() *types.UInt32Value { if m != nil { - return m.Rx1Delay + return m.Rx1DataRateOffset } return nil } @@ -918,56 +948,95 @@ func (m *MACSettings) GetRx2DataRateIndex() *MACSettings_DataRateIndexValue { return nil } -func (m *MACSettings) GetRx2Frequency() *types.UInt64Value { +func (m *MACSettings) GetRx2Frequency() uint64 { if m != nil { return m.Rx2Frequency } + return 0 +} + +func (m *MACSettings) GetFactoryPresetFrequencies() []uint64 { + if m != nil { + return m.FactoryPresetFrequencies + } return nil } -type MACSettings_RxDelayValue struct { - Value RxDelay `protobuf:"varint,1,opt,name=value,proto3,enum=ttn.lorawan.v3.RxDelay" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_sizecache int32 `json:"-"` +func (m *MACSettings) GetMaxDutyCycle() *MACSettings_AggregatedDutyCycleValue { + if m != nil { + return m.MaxDutyCycle + } + return nil } -func (m *MACSettings_RxDelayValue) Reset() { *m = MACSettings_RxDelayValue{} } -func (*MACSettings_RxDelayValue) ProtoMessage() {} -func (*MACSettings_RxDelayValue) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{6, 0} +func (m *MACSettings) GetSupports32BitFCnt() *types.BoolValue { + if m != nil { + return m.Supports32BitFCnt + } + return nil } -func (m *MACSettings_RxDelayValue) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) + +func (m *MACSettings) GetUseADR() *types.BoolValue { + if m != nil { + return m.UseADR + } + return nil } -func (m *MACSettings_RxDelayValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_MACSettings_RxDelayValue.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil + +func (m *MACSettings) GetADRMargin() *types.FloatValue { + if m != nil { + return m.ADRMargin } + return nil } -func (dst *MACSettings_RxDelayValue) XXX_Merge(src proto.Message) { - xxx_messageInfo_MACSettings_RxDelayValue.Merge(dst, src) + +func (m *MACSettings) GetResetsFCnt() *types.BoolValue { + if m != nil { + return m.ResetsFCnt + } + return nil } -func (m *MACSettings_RxDelayValue) XXX_Size() int { - return m.Size() + +func (m *MACSettings) GetStatusTimePeriodicity() *time.Duration { + if m != nil { + return m.StatusTimePeriodicity + } + return nil } -func (m *MACSettings_RxDelayValue) XXX_DiscardUnknown() { - xxx_messageInfo_MACSettings_RxDelayValue.DiscardUnknown(m) + +func (m *MACSettings) GetStatusCountPeriodicity() *types.UInt32Value { + if m != nil { + return m.StatusCountPeriodicity + } + return nil } -var xxx_messageInfo_MACSettings_RxDelayValue proto.InternalMessageInfo +func (m *MACSettings) GetDesiredRx1Delay() *MACSettings_RxDelayValue { + if m != nil { + return m.DesiredRx1Delay + } + return nil +} -func (m *MACSettings_RxDelayValue) GetValue() RxDelay { +func (m *MACSettings) GetDesiredRx1DataRateOffset() *types.UInt32Value { if m != nil { - return m.Value + return m.DesiredRx1DataRateOffset } - return RX_DELAY_0 + return nil +} + +func (m *MACSettings) GetDesiredRx2DataRateIndex() *MACSettings_DataRateIndexValue { + if m != nil { + return m.DesiredRx2DataRateIndex + } + return nil +} + +func (m *MACSettings) GetDesiredRx2Frequency() uint64 { + if m != nil { + return m.DesiredRx2Frequency + } + return 0 } type MACSettings_DataRateIndexValue struct { @@ -979,7 +1048,7 @@ type MACSettings_DataRateIndexValue struct { func (m *MACSettings_DataRateIndexValue) Reset() { *m = MACSettings_DataRateIndexValue{} } func (*MACSettings_DataRateIndexValue) ProtoMessage() {} func (*MACSettings_DataRateIndexValue) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{6, 1} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{6, 0} } func (m *MACSettings_DataRateIndexValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1015,60 +1084,23 @@ func (m *MACSettings_DataRateIndexValue) GetValue() DataRateIndex { return DATA_RATE_0 } -// MACState represents the state of MAC layer of the device. -// MACState is reset on each join for OTAA or ResetInd for ABP devices. -// This is used internally by the Network Server and is read only. -type MACState struct { - // Current LoRaWAN MAC parameters. - CurrentParameters MACParameters `protobuf:"bytes,1,opt,name=current_parameters,json=currentParameters,proto3" json:"current_parameters"` - // Desired LoRaWAN MAC parameters. - DesiredParameters MACParameters `protobuf:"bytes,2,opt,name=desired_parameters,json=desiredParameters,proto3" json:"desired_parameters"` - // Currently active LoRaWAN device class - // - Device class is A by default - // - If device sets ClassB bit in uplink, this will be set to B - // - If device sent DeviceModeInd MAC message, this will be set to that value - DeviceClass Class `protobuf:"varint,3,opt,name=device_class,json=deviceClass,proto3,enum=ttn.lorawan.v3.Class" json:"device_class,omitempty"` - // LoRaWAN MAC version. - LoRaWANVersion MACVersion `protobuf:"varint,4,opt,name=lorawan_version,json=lorawanVersion,proto3,enum=ttn.lorawan.v3.MACVersion" json:"lorawan_version,omitempty"` - // Time when the last confirmed downlink message or MAC command was scheduled. - LastConfirmedDownlinkAt *time.Time `protobuf:"bytes,5,opt,name=last_confirmed_downlink_at,json=lastConfirmedDownlinkAt,proto3,stdtime" json:"last_confirmed_downlink_at,omitempty"` - // Frame counter value of last uplink containing DevStatusAns. - LastDevStatusFCntUp uint32 `protobuf:"varint,6,opt,name=last_dev_status_f_cnt_up,json=lastDevStatusFCntUp,proto3" json:"last_dev_status_f_cnt_up,omitempty"` - // Periodicity of the class B ping slot. - PingSlotPeriodicity PingSlotPeriod `protobuf:"varint,7,opt,name=ping_slot_periodicity,json=pingSlotPeriodicity,proto3,enum=ttn.lorawan.v3.PingSlotPeriod" json:"ping_slot_periodicity,omitempty"` - // A confirmed application downlink, for which an acknowledgment is expected to arrive. - PendingApplicationDownlink *ApplicationDownlink `protobuf:"bytes,8,opt,name=pending_application_downlink,json=pendingApplicationDownlink,proto3" json:"pending_application_downlink,omitempty"` - // Queued MAC responses. - // Regenerated on each uplink. - QueuedResponses []*MACCommand `protobuf:"bytes,9,rep,name=queued_responses,json=queuedResponses,proto3" json:"queued_responses,omitempty"` - // Pending MAC requests(i.e. sent requests, for which no response has been received yet). - // Regenerated on each downlink. - PendingRequests []*MACCommand `protobuf:"bytes,10,rep,name=pending_requests,json=pendingRequests,proto3" json:"pending_requests,omitempty"` - // Queued join-accept. - // Set each time a (re-)join request accept is received from Join Server and removed each time a downlink is scheduled. - QueuedJoinAccept *MACState_JoinAccept `protobuf:"bytes,11,opt,name=queued_join_accept,json=queuedJoinAccept,proto3" json:"queued_join_accept,omitempty"` - // Pending join request. - // Set each time a join accept is scheduled and removed each time an uplink is received from the device. - PendingJoinRequest *JoinRequest `protobuf:"bytes,12,opt,name=pending_join_request,json=pendingJoinRequest,proto3" json:"pending_join_request,omitempty"` - // Whether or not Rx windows are expected to be open. - // Set to true every time an uplink is received. - // Set to false every time a successful downlink scheduling attempt is made. - RxWindowsAvailable bool `protobuf:"varint,13,opt,name=rx_windows_available,json=rxWindowsAvailable,proto3" json:"rx_windows_available,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_sizecache int32 `json:"-"` +type MACSettings_PingSlotPeriodValue struct { + Value PingSlotPeriod `protobuf:"varint,1,opt,name=value,proto3,enum=ttn.lorawan.v3.PingSlotPeriod" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *MACState) Reset() { *m = MACState{} } -func (*MACState) ProtoMessage() {} -func (*MACState) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{7} +func (m *MACSettings_PingSlotPeriodValue) Reset() { *m = MACSettings_PingSlotPeriodValue{} } +func (*MACSettings_PingSlotPeriodValue) ProtoMessage() {} +func (*MACSettings_PingSlotPeriodValue) Descriptor() ([]byte, []int) { + return fileDescriptor_end_device_7df2e0db88789f5d, []int{6, 1} } -func (m *MACState) XXX_Unmarshal(b []byte) error { +func (m *MACSettings_PingSlotPeriodValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *MACState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *MACSettings_PingSlotPeriodValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_MACState.Marshal(b, m, deterministic) + return xxx_messageInfo_MACSettings_PingSlotPeriodValue.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalTo(b) @@ -1078,56 +1110,228 @@ func (m *MACState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } -func (dst *MACState) XXX_Merge(src proto.Message) { - xxx_messageInfo_MACState.Merge(dst, src) +func (dst *MACSettings_PingSlotPeriodValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_MACSettings_PingSlotPeriodValue.Merge(dst, src) } -func (m *MACState) XXX_Size() int { +func (m *MACSettings_PingSlotPeriodValue) XXX_Size() int { return m.Size() } -func (m *MACState) XXX_DiscardUnknown() { - xxx_messageInfo_MACState.DiscardUnknown(m) +func (m *MACSettings_PingSlotPeriodValue) XXX_DiscardUnknown() { + xxx_messageInfo_MACSettings_PingSlotPeriodValue.DiscardUnknown(m) } -var xxx_messageInfo_MACState proto.InternalMessageInfo +var xxx_messageInfo_MACSettings_PingSlotPeriodValue proto.InternalMessageInfo -func (m *MACState) GetCurrentParameters() MACParameters { +func (m *MACSettings_PingSlotPeriodValue) GetValue() PingSlotPeriod { if m != nil { - return m.CurrentParameters + return m.Value } - return MACParameters{} + return PING_EVERY_1S } -func (m *MACState) GetDesiredParameters() MACParameters { - if m != nil { - return m.DesiredParameters - } - return MACParameters{} +type MACSettings_AggregatedDutyCycleValue struct { + Value AggregatedDutyCycle `protobuf:"varint,1,opt,name=value,proto3,enum=ttn.lorawan.v3.AggregatedDutyCycle" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *MACState) GetDeviceClass() Class { - if m != nil { - return m.DeviceClass - } - return CLASS_A +func (m *MACSettings_AggregatedDutyCycleValue) Reset() { *m = MACSettings_AggregatedDutyCycleValue{} } +func (*MACSettings_AggregatedDutyCycleValue) ProtoMessage() {} +func (*MACSettings_AggregatedDutyCycleValue) Descriptor() ([]byte, []int) { + return fileDescriptor_end_device_7df2e0db88789f5d, []int{6, 2} } - -func (m *MACState) GetLoRaWANVersion() MACVersion { - if m != nil { - return m.LoRaWANVersion +func (m *MACSettings_AggregatedDutyCycleValue) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MACSettings_AggregatedDutyCycleValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MACSettings_AggregatedDutyCycleValue.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return MAC_UNKNOWN +} +func (dst *MACSettings_AggregatedDutyCycleValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_MACSettings_AggregatedDutyCycleValue.Merge(dst, src) +} +func (m *MACSettings_AggregatedDutyCycleValue) XXX_Size() int { + return m.Size() +} +func (m *MACSettings_AggregatedDutyCycleValue) XXX_DiscardUnknown() { + xxx_messageInfo_MACSettings_AggregatedDutyCycleValue.DiscardUnknown(m) } -func (m *MACState) GetLastConfirmedDownlinkAt() *time.Time { +var xxx_messageInfo_MACSettings_AggregatedDutyCycleValue proto.InternalMessageInfo + +func (m *MACSettings_AggregatedDutyCycleValue) GetValue() AggregatedDutyCycle { if m != nil { - return m.LastConfirmedDownlinkAt + return m.Value } - return nil + return DUTY_CYCLE_1 } -func (m *MACState) GetLastDevStatusFCntUp() uint32 { - if m != nil { - return m.LastDevStatusFCntUp +type MACSettings_RxDelayValue struct { + Value RxDelay `protobuf:"varint,1,opt,name=value,proto3,enum=ttn.lorawan.v3.RxDelay" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MACSettings_RxDelayValue) Reset() { *m = MACSettings_RxDelayValue{} } +func (*MACSettings_RxDelayValue) ProtoMessage() {} +func (*MACSettings_RxDelayValue) Descriptor() ([]byte, []int) { + return fileDescriptor_end_device_7df2e0db88789f5d, []int{6, 3} +} +func (m *MACSettings_RxDelayValue) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MACSettings_RxDelayValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MACSettings_RxDelayValue.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *MACSettings_RxDelayValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_MACSettings_RxDelayValue.Merge(dst, src) +} +func (m *MACSettings_RxDelayValue) XXX_Size() int { + return m.Size() +} +func (m *MACSettings_RxDelayValue) XXX_DiscardUnknown() { + xxx_messageInfo_MACSettings_RxDelayValue.DiscardUnknown(m) +} + +var xxx_messageInfo_MACSettings_RxDelayValue proto.InternalMessageInfo + +func (m *MACSettings_RxDelayValue) GetValue() RxDelay { + if m != nil { + return m.Value + } + return RX_DELAY_0 +} + +// MACState represents the state of MAC layer of the device. +// MACState is reset on each join for OTAA or ResetInd for ABP devices. +// This is used internally by the Network Server and is read only. +type MACState struct { + // Current LoRaWAN MAC parameters. + CurrentParameters MACParameters `protobuf:"bytes,1,opt,name=current_parameters,json=currentParameters,proto3" json:"current_parameters"` + // Desired LoRaWAN MAC parameters. + DesiredParameters MACParameters `protobuf:"bytes,2,opt,name=desired_parameters,json=desiredParameters,proto3" json:"desired_parameters"` + // Currently active LoRaWAN device class + // - Device class is A by default + // - If device sets ClassB bit in uplink, this will be set to B + // - If device sent DeviceModeInd MAC message, this will be set to that value + DeviceClass Class `protobuf:"varint,3,opt,name=device_class,json=deviceClass,proto3,enum=ttn.lorawan.v3.Class" json:"device_class,omitempty"` + // LoRaWAN MAC version. + LoRaWANVersion MACVersion `protobuf:"varint,4,opt,name=lorawan_version,json=lorawanVersion,proto3,enum=ttn.lorawan.v3.MACVersion" json:"lorawan_version,omitempty"` + // Time when the last confirmed downlink message or MAC command was scheduled. + LastConfirmedDownlinkAt *time.Time `protobuf:"bytes,5,opt,name=last_confirmed_downlink_at,json=lastConfirmedDownlinkAt,proto3,stdtime" json:"last_confirmed_downlink_at,omitempty"` + // Frame counter value of last uplink containing DevStatusAns. + LastDevStatusFCntUp uint32 `protobuf:"varint,6,opt,name=last_dev_status_f_cnt_up,json=lastDevStatusFCntUp,proto3" json:"last_dev_status_f_cnt_up,omitempty"` + // Periodicity of the class B ping slot. + PingSlotPeriodicity PingSlotPeriod `protobuf:"varint,7,opt,name=ping_slot_periodicity,json=pingSlotPeriodicity,proto3,enum=ttn.lorawan.v3.PingSlotPeriod" json:"ping_slot_periodicity,omitempty"` + // A confirmed application downlink, for which an acknowledgment is expected to arrive. + PendingApplicationDownlink *ApplicationDownlink `protobuf:"bytes,8,opt,name=pending_application_downlink,json=pendingApplicationDownlink,proto3" json:"pending_application_downlink,omitempty"` + // Queued MAC responses. + // Regenerated on each uplink. + QueuedResponses []*MACCommand `protobuf:"bytes,9,rep,name=queued_responses,json=queuedResponses,proto3" json:"queued_responses,omitempty"` + // Pending MAC requests(i.e. sent requests, for which no response has been received yet). + // Regenerated on each downlink. + PendingRequests []*MACCommand `protobuf:"bytes,10,rep,name=pending_requests,json=pendingRequests,proto3" json:"pending_requests,omitempty"` + // Queued join-accept. + // Set each time a (re-)join request accept is received from Join Server and removed each time a downlink is scheduled. + QueuedJoinAccept *MACState_JoinAccept `protobuf:"bytes,11,opt,name=queued_join_accept,json=queuedJoinAccept,proto3" json:"queued_join_accept,omitempty"` + // Pending join request. + // Set each time a join accept is scheduled and removed each time an uplink is received from the device. + PendingJoinRequest *JoinRequest `protobuf:"bytes,12,opt,name=pending_join_request,json=pendingJoinRequest,proto3" json:"pending_join_request,omitempty"` + // Whether or not Rx windows are expected to be open. + // Set to true every time an uplink is received. + // Set to false every time a successful downlink scheduling attempt is made. + RxWindowsAvailable bool `protobuf:"varint,13,opt,name=rx_windows_available,json=rxWindowsAvailable,proto3" json:"rx_windows_available,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MACState) Reset() { *m = MACState{} } +func (*MACState) ProtoMessage() {} +func (*MACState) Descriptor() ([]byte, []int) { + return fileDescriptor_end_device_7df2e0db88789f5d, []int{7} +} +func (m *MACState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MACState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MACState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *MACState) XXX_Merge(src proto.Message) { + xxx_messageInfo_MACState.Merge(dst, src) +} +func (m *MACState) XXX_Size() int { + return m.Size() +} +func (m *MACState) XXX_DiscardUnknown() { + xxx_messageInfo_MACState.DiscardUnknown(m) +} + +var xxx_messageInfo_MACState proto.InternalMessageInfo + +func (m *MACState) GetCurrentParameters() MACParameters { + if m != nil { + return m.CurrentParameters + } + return MACParameters{} +} + +func (m *MACState) GetDesiredParameters() MACParameters { + if m != nil { + return m.DesiredParameters + } + return MACParameters{} +} + +func (m *MACState) GetDeviceClass() Class { + if m != nil { + return m.DeviceClass + } + return CLASS_A +} + +func (m *MACState) GetLoRaWANVersion() MACVersion { + if m != nil { + return m.LoRaWANVersion + } + return MAC_UNKNOWN +} + +func (m *MACState) GetLastConfirmedDownlinkAt() *time.Time { + if m != nil { + return m.LastConfirmedDownlinkAt + } + return nil +} + +func (m *MACState) GetLastDevStatusFCntUp() uint32 { + if m != nil { + return m.LastDevStatusFCntUp } return 0 } @@ -1195,7 +1399,7 @@ type MACState_JoinAccept struct { func (m *MACState_JoinAccept) Reset() { *m = MACState_JoinAccept{} } func (*MACState_JoinAccept) ProtoMessage() {} func (*MACState_JoinAccept) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{7, 0} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{7, 0} } func (m *MACState_JoinAccept) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1300,91 +1504,82 @@ type EndDevice struct { // ID of the frequency plan used by this device. // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. FrequencyPlanID string `protobuf:"bytes,17,opt,name=frequency_plan_id,json=frequencyPlanId,proto3" json:"frequency_plan_id,omitempty"` - // Default MAC layer parameters, to which device is reset by default (e.g. on join or ResetInd). Stored in Network Server. - // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - DefaultMACParameters *MACParameters `protobuf:"bytes,18,opt,name=default_mac_parameters,json=defaultMacParameters,proto3" json:"default_mac_parameters,omitempty"` // Minimum frequency the device is capable of using (Hz). Stored in Network Server. // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - MinFrequency uint64 `protobuf:"varint,19,opt,name=min_frequency,json=minFrequency,proto3" json:"min_frequency,omitempty"` + MinFrequency uint64 `protobuf:"varint,18,opt,name=min_frequency,json=minFrequency,proto3" json:"min_frequency,omitempty"` // Maximum frequency the device is capable of using (Hz). Stored in Network Server. // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - MaxFrequency uint64 `protobuf:"varint,20,opt,name=max_frequency,json=maxFrequency,proto3" json:"max_frequency,omitempty"` - // Whether the device resets the frame counters (not LoRaWAN compliant). Stored in Network Server. - // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - ResetsFCnt bool `protobuf:"varint,21,opt,name=resets_f_cnt,json=resetsFCnt,proto3" json:"resets_f_cnt,omitempty"` - // Whether the device uses 32-bit frame counters. Stored in Network Server. - // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - Uses32BitFCnt bool `protobuf:"varint,22,opt,name=uses_32_bit_f_cnt,json=uses32BitFCnt,proto3" json:"uses_32_bit_f_cnt,omitempty"` + MaxFrequency uint64 `protobuf:"varint,19,opt,name=max_frequency,json=maxFrequency,proto3" json:"max_frequency,omitempty"` // The device supports join (it's OTAA). // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - SupportsJoin bool `protobuf:"varint,23,opt,name=supports_join,json=supportsJoin,proto3" json:"supports_join,omitempty"` - // Whether the device resets the join and dev nonces (not LoRaWAN 1.1 compliant). Stored in Network Server. + SupportsJoin bool `protobuf:"varint,20,opt,name=supports_join,json=supportsJoin,proto3" json:"supports_join,omitempty"` + // Whether the device resets the join and dev nonces (not LoRaWAN 1.1 compliant). Stored in Join Server. // Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any. - ResetsJoinNonces bool `protobuf:"varint,24,opt,name=resets_join_nonces,json=resetsJoinNonces,proto3" json:"resets_join_nonces,omitempty"` + ResetsJoinNonces bool `protobuf:"varint,21,opt,name=resets_join_nonces,json=resetsJoinNonces,proto3" json:"resets_join_nonces,omitempty"` // Device root keys. Stored in Join Server. - RootKeys *RootKeys `protobuf:"bytes,25,opt,name=root_keys,json=rootKeys,proto3" json:"root_keys,omitempty"` + RootKeys *RootKeys `protobuf:"bytes,22,opt,name=root_keys,json=rootKeys,proto3" json:"root_keys,omitempty"` // Home NetID. Stored in Join Server. - NetID *go_thethings_network_lorawan_stack_pkg_types.NetID `protobuf:"bytes,26,opt,name=net_id,json=netId,proto3,customtype=go.thethings.network/lorawan-stack/pkg/types.NetID" json:"net_id,omitempty"` - // Settings for how the Network Server handles MAC for this device. Stored in Network Server. - MACSettings *MACSettings `protobuf:"bytes,27,opt,name=mac_settings,json=macSettings,proto3" json:"mac_settings,omitempty"` + NetID *go_thethings_network_lorawan_stack_pkg_types.NetID `protobuf:"bytes,23,opt,name=net_id,json=netId,proto3,customtype=go.thethings.network/lorawan-stack/pkg/types.NetID" json:"net_id,omitempty"` + // Settings for how the Network Server handles MAC layer for this device. Stored in Network Server. + MACSettings *MACSettings `protobuf:"bytes,24,opt,name=mac_settings,json=macSettings,proto3" json:"mac_settings,omitempty"` // MAC state of the device. Stored in Network Server. - MACState *MACState `protobuf:"bytes,28,opt,name=mac_state,json=macState,proto3" json:"mac_state,omitempty"` + MACState *MACState `protobuf:"bytes,25,opt,name=mac_state,json=macState,proto3" json:"mac_state,omitempty"` // Current session of the device. Stored in Network Server and Application Server. - Session *Session `protobuf:"bytes,29,opt,name=session,proto3" json:"session,omitempty"` + Session *Session `protobuf:"bytes,26,opt,name=session,proto3" json:"session,omitempty"` // Pending session. Stored in Network Server and Application Server until RekeyInd is received. - PendingSession *Session `protobuf:"bytes,30,opt,name=pending_session,json=pendingSession,proto3" json:"pending_session,omitempty"` + PendingSession *Session `protobuf:"bytes,27,opt,name=pending_session,json=pendingSession,proto3" json:"pending_session,omitempty"` // Last DevNonce used. // This field is only used for devices using LoRaWAN version 1.1 and later. // Stored in Join Server. - LastDevNonce uint32 `protobuf:"varint,31,opt,name=last_dev_nonce,json=lastDevNonce,proto3" json:"last_dev_nonce,omitempty"` + LastDevNonce uint32 `protobuf:"varint,28,opt,name=last_dev_nonce,json=lastDevNonce,proto3" json:"last_dev_nonce,omitempty"` // Used DevNonces sorted in ascending order. // This field is only used for devices using LoRaWAN versions preceding 1.1. // Stored in Join Server. - UsedDevNonces []uint32 `protobuf:"varint,32,rep,packed,name=used_dev_nonces,json=usedDevNonces,proto3" json:"used_dev_nonces,omitempty"` + UsedDevNonces []uint32 `protobuf:"varint,29,rep,packed,name=used_dev_nonces,json=usedDevNonces,proto3" json:"used_dev_nonces,omitempty"` // Last JoinNonce/AppNonce(for devices using LoRaWAN versions preceding 1.1) used. // Stored in Join Server. - LastJoinNonce uint32 `protobuf:"varint,33,opt,name=last_join_nonce,json=lastJoinNonce,proto3" json:"last_join_nonce,omitempty"` + LastJoinNonce uint32 `protobuf:"varint,30,opt,name=last_join_nonce,json=lastJoinNonce,proto3" json:"last_join_nonce,omitempty"` // Last Rejoin counter value used (type 0/2). // Stored in Join Server. - LastRJCount0 uint32 `protobuf:"varint,34,opt,name=last_rj_count_0,json=lastRjCount0,proto3" json:"last_rj_count_0,omitempty"` + LastRJCount0 uint32 `protobuf:"varint,31,opt,name=last_rj_count_0,json=lastRjCount0,proto3" json:"last_rj_count_0,omitempty"` // Last Rejoin counter value used (type 1). // Stored in Join Server. - LastRJCount1 uint32 `protobuf:"varint,35,opt,name=last_rj_count_1,json=lastRjCount1,proto3" json:"last_rj_count_1,omitempty"` + LastRJCount1 uint32 `protobuf:"varint,32,opt,name=last_rj_count_1,json=lastRjCount1,proto3" json:"last_rj_count_1,omitempty"` // Time when last DevStatus MAC command was received. // Stored in Network Server. - LastDevStatusReceivedAt *time.Time `protobuf:"bytes,36,opt,name=last_dev_status_received_at,json=lastDevStatusReceivedAt,proto3,stdtime" json:"last_dev_status_received_at,omitempty"` + LastDevStatusReceivedAt *time.Time `protobuf:"bytes,33,opt,name=last_dev_status_received_at,json=lastDevStatusReceivedAt,proto3,stdtime" json:"last_dev_status_received_at,omitempty"` // The power state of the device; whether it is battery-powered or connected to an external power source. // Received via the DevStatus MAC command at status_received_at. // Stored in Network Server. - PowerState PowerState `protobuf:"varint,37,opt,name=power_state,json=powerState,proto3,enum=ttn.lorawan.v3.PowerState" json:"power_state,omitempty"` + PowerState PowerState `protobuf:"varint,34,opt,name=power_state,json=powerState,proto3,enum=ttn.lorawan.v3.PowerState" json:"power_state,omitempty"` // Latest-known battery percentage of the device. // Received via the DevStatus MAC command at last_dev_status_received_at or earlier. // Stored in Network Server. - BatteryPercentage float32 `protobuf:"fixed32,38,opt,name=battery_percentage,json=batteryPercentage,proto3" json:"battery_percentage,omitempty"` + BatteryPercentage float32 `protobuf:"fixed32,35,opt,name=battery_percentage,json=batteryPercentage,proto3" json:"battery_percentage,omitempty"` // Demodulation signal-to-noise ratio (dB). // Received via the DevStatus MAC command at last_dev_status_received_at. // Stored in Network Server. - DownlinkMargin int32 `protobuf:"varint,39,opt,name=downlink_margin,json=downlinkMargin,proto3" json:"downlink_margin,omitempty"` + DownlinkMargin int32 `protobuf:"varint,36,opt,name=downlink_margin,json=downlinkMargin,proto3" json:"downlink_margin,omitempty"` // Recent uplink messages with ADR bit set to 1 sorted by time. Stored in Network Server. // The field is reset each time an uplink message carrying MACPayload is received with ADR bit set to 0. // The number of messages stored is in the range [0,20]; - RecentADRUplinks []*UplinkMessage `protobuf:"bytes,40,rep,name=recent_adr_uplinks,json=recentAdrUplinks,proto3" json:"recent_adr_uplinks,omitempty"` + RecentADRUplinks []*UplinkMessage `protobuf:"bytes,37,rep,name=recent_adr_uplinks,json=recentAdrUplinks,proto3" json:"recent_adr_uplinks,omitempty"` // Recent uplink messages sorted by time. Stored in Network Server. // The number of messages stored may depend on configuration. - RecentUplinks []*UplinkMessage `protobuf:"bytes,41,rep,name=recent_uplinks,json=recentUplinks,proto3" json:"recent_uplinks,omitempty"` + RecentUplinks []*UplinkMessage `protobuf:"bytes,38,rep,name=recent_uplinks,json=recentUplinks,proto3" json:"recent_uplinks,omitempty"` // Recent downlink messages sorted by time. Stored in Network Server. // The number of messages stored may depend on configuration. - RecentDownlinks []*DownlinkMessage `protobuf:"bytes,42,rep,name=recent_downlinks,json=recentDownlinks,proto3" json:"recent_downlinks,omitempty"` + RecentDownlinks []*DownlinkMessage `protobuf:"bytes,39,rep,name=recent_downlinks,json=recentDownlinks,proto3" json:"recent_downlinks,omitempty"` // Queued Application downlink messages. Stored in Application Server, // which sets them on the Network Server. - QueuedApplicationDownlinks []*ApplicationDownlink `protobuf:"bytes,43,rep,name=queued_application_downlinks,json=queuedApplicationDownlinks,proto3" json:"queued_application_downlinks,omitempty"` + QueuedApplicationDownlinks []*ApplicationDownlink `protobuf:"bytes,40,rep,name=queued_application_downlinks,json=queuedApplicationDownlinks,proto3" json:"queued_application_downlinks,omitempty"` // The payload formatters for this end device. Stored in Application Server. // Copied on creation from template identified by version_ids. - Formatters *MessagePayloadFormatters `protobuf:"bytes,44,opt,name=formatters,proto3" json:"formatters,omitempty"` + Formatters *MessagePayloadFormatters `protobuf:"bytes,41,opt,name=formatters,proto3" json:"formatters,omitempty"` // ID of the provisioner. Stored in Join Server. - ProvisionerID string `protobuf:"bytes,45,opt,name=provisioner_id,json=provisionerId,proto3" json:"provisioner_id,omitempty"` + ProvisionerID string `protobuf:"bytes,42,opt,name=provisioner_id,json=provisionerId,proto3" json:"provisioner_id,omitempty"` // Vendor-specific provisioning data. Stored in Join Server. - ProvisioningData *types.Struct `protobuf:"bytes,46,opt,name=provisioning_data,json=provisioningData,proto3" json:"provisioning_data,omitempty"` + ProvisioningData *types.Struct `protobuf:"bytes,43,opt,name=provisioning_data,json=provisioningData,proto3" json:"provisioning_data,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_sizecache int32 `json:"-"` } @@ -1392,7 +1587,7 @@ type EndDevice struct { func (m *EndDevice) Reset() { *m = EndDevice{} } func (*EndDevice) ProtoMessage() {} func (*EndDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{8} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{8} } func (m *EndDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1533,13 +1728,6 @@ func (m *EndDevice) GetFrequencyPlanID() string { return "" } -func (m *EndDevice) GetDefaultMACParameters() *MACParameters { - if m != nil { - return m.DefaultMACParameters - } - return nil -} - func (m *EndDevice) GetMinFrequency() uint64 { if m != nil { return m.MinFrequency @@ -1554,20 +1742,6 @@ func (m *EndDevice) GetMaxFrequency() uint64 { return 0 } -func (m *EndDevice) GetResetsFCnt() bool { - if m != nil { - return m.ResetsFCnt - } - return false -} - -func (m *EndDevice) GetUses32BitFCnt() bool { - if m != nil { - return m.Uses32BitFCnt - } - return false -} - func (m *EndDevice) GetSupportsJoin() bool { if m != nil { return m.SupportsJoin @@ -1738,7 +1912,7 @@ type EndDevices struct { func (m *EndDevices) Reset() { *m = EndDevices{} } func (*EndDevices) ProtoMessage() {} func (*EndDevices) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{9} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{9} } func (m *EndDevices) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1783,7 +1957,7 @@ type CreateEndDeviceRequest struct { func (m *CreateEndDeviceRequest) Reset() { *m = CreateEndDeviceRequest{} } func (*CreateEndDeviceRequest) ProtoMessage() {} func (*CreateEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{10} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{10} } func (m *CreateEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1822,7 +1996,7 @@ type UpdateEndDeviceRequest struct { func (m *UpdateEndDeviceRequest) Reset() { *m = UpdateEndDeviceRequest{} } func (*UpdateEndDeviceRequest) ProtoMessage() {} func (*UpdateEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{11} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{11} } func (m *UpdateEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1868,7 +2042,7 @@ type GetEndDeviceRequest struct { func (m *GetEndDeviceRequest) Reset() { *m = GetEndDeviceRequest{} } func (*GetEndDeviceRequest) ProtoMessage() {} func (*GetEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{12} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{12} } func (m *GetEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1921,7 +2095,7 @@ type ListEndDevicesRequest struct { func (m *ListEndDevicesRequest) Reset() { *m = ListEndDevicesRequest{} } func (*ListEndDevicesRequest) ProtoMessage() {} func (*ListEndDevicesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{13} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{13} } func (m *ListEndDevicesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1988,7 +2162,7 @@ type SetEndDeviceRequest struct { func (m *SetEndDeviceRequest) Reset() { *m = SetEndDeviceRequest{} } func (*SetEndDeviceRequest) ProtoMessage() {} func (*SetEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_f29faf389d9d861a, []int{14} + return fileDescriptor_end_device_7df2e0db88789f5d, []int{14} } func (m *SetEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2048,10 +2222,14 @@ func init() { golang_proto.RegisterType((*EndDeviceVersion)(nil), "ttn.lorawan.v3.EndDeviceVersion") proto.RegisterType((*MACSettings)(nil), "ttn.lorawan.v3.MACSettings") golang_proto.RegisterType((*MACSettings)(nil), "ttn.lorawan.v3.MACSettings") - proto.RegisterType((*MACSettings_RxDelayValue)(nil), "ttn.lorawan.v3.MACSettings.RxDelayValue") - golang_proto.RegisterType((*MACSettings_RxDelayValue)(nil), "ttn.lorawan.v3.MACSettings.RxDelayValue") proto.RegisterType((*MACSettings_DataRateIndexValue)(nil), "ttn.lorawan.v3.MACSettings.DataRateIndexValue") golang_proto.RegisterType((*MACSettings_DataRateIndexValue)(nil), "ttn.lorawan.v3.MACSettings.DataRateIndexValue") + proto.RegisterType((*MACSettings_PingSlotPeriodValue)(nil), "ttn.lorawan.v3.MACSettings.PingSlotPeriodValue") + golang_proto.RegisterType((*MACSettings_PingSlotPeriodValue)(nil), "ttn.lorawan.v3.MACSettings.PingSlotPeriodValue") + proto.RegisterType((*MACSettings_AggregatedDutyCycleValue)(nil), "ttn.lorawan.v3.MACSettings.AggregatedDutyCycleValue") + golang_proto.RegisterType((*MACSettings_AggregatedDutyCycleValue)(nil), "ttn.lorawan.v3.MACSettings.AggregatedDutyCycleValue") + proto.RegisterType((*MACSettings_RxDelayValue)(nil), "ttn.lorawan.v3.MACSettings.RxDelayValue") + golang_proto.RegisterType((*MACSettings_RxDelayValue)(nil), "ttn.lorawan.v3.MACSettings.RxDelayValue") proto.RegisterType((*MACState)(nil), "ttn.lorawan.v3.MACState") golang_proto.RegisterType((*MACState)(nil), "ttn.lorawan.v3.MACState") proto.RegisterType((*MACState_JoinAccept)(nil), "ttn.lorawan.v3.MACState.JoinAccept") @@ -2181,13 +2359,22 @@ func (this *MACParameters) Equal(that interface{}) bool { if this.Rx2Frequency != that1.Rx2Frequency { return false } + if this.MaxDutyCycle != that1.MaxDutyCycle { + return false + } if this.RejoinTimePeriodicity != that1.RejoinTimePeriodicity { return false } if this.RejoinCountPeriodicity != that1.RejoinCountPeriodicity { return false } - if this.MaxDutyCycle != that1.MaxDutyCycle { + if this.PingSlotFrequency != that1.PingSlotFrequency { + return false + } + if this.PingSlotDataRateIndex != that1.PingSlotDataRateIndex { + return false + } + if this.BeaconFrequency != that1.BeaconFrequency { return false } if len(this.Channels) != len(that1.Channels) { @@ -2198,15 +2385,6 @@ func (this *MACParameters) Equal(that interface{}) bool { return false } } - if this.PingSlotFrequency != that1.PingSlotFrequency { - return false - } - if this.PingSlotDataRateIndex != that1.PingSlotDataRateIndex { - return false - } - if this.BeaconFrequency != that1.BeaconFrequency { - return false - } return true } func (this *MACParameters_Channel) Equal(that interface{}) bool { @@ -2391,7 +2569,7 @@ func (this *EndDeviceVersion) Equal(that interface{}) bool { if this.SupportsClassC != that1.SupportsClassC { return false } - if !this.DefaultMACParameters.Equal(that1.DefaultMACParameters) { + if !this.DefaultMACSettings.Equal(that1.DefaultMACSettings) { return false } if this.MinFrequency != that1.MinFrequency { @@ -2403,9 +2581,6 @@ func (this *EndDeviceVersion) Equal(that interface{}) bool { if this.ResetsFCnt != that1.ResetsFCnt { return false } - if this.Uses32BitFCnt != that1.Uses32BitFCnt { - return false - } if this.SupportsJoin != that1.SupportsJoin { return false } @@ -2436,12 +2611,6 @@ func (this *MACSettings) Equal(that interface{}) bool { } else if this == nil { return false } - if !this.UseADR.Equal(that1.UseADR) { - return false - } - if !this.ADRMargin.Equal(that1.ADRMargin) { - return false - } if this.ClassBTimeout != nil && that1.ClassBTimeout != nil { if *this.ClassBTimeout != *that1.ClassBTimeout { return false @@ -2451,6 +2620,15 @@ func (this *MACSettings) Equal(that interface{}) bool { } else if that1.ClassBTimeout != nil { return false } + if !this.PingSlotPeriodicity.Equal(that1.PingSlotPeriodicity) { + return false + } + if !this.PingSlotDataRateIndex.Equal(that1.PingSlotDataRateIndex) { + return false + } + if this.PingSlotFrequency != that1.PingSlotFrequency { + return false + } if this.ClassCTimeout != nil && that1.ClassCTimeout != nil { if *this.ClassCTimeout != *that1.ClassCTimeout { return false @@ -2460,6 +2638,41 @@ func (this *MACSettings) Equal(that interface{}) bool { } else if that1.ClassCTimeout != nil { return false } + if !this.Rx1Delay.Equal(that1.Rx1Delay) { + return false + } + if !this.Rx1DataRateOffset.Equal(that1.Rx1DataRateOffset) { + return false + } + if !this.Rx2DataRateIndex.Equal(that1.Rx2DataRateIndex) { + return false + } + if this.Rx2Frequency != that1.Rx2Frequency { + return false + } + if len(this.FactoryPresetFrequencies) != len(that1.FactoryPresetFrequencies) { + return false + } + for i := range this.FactoryPresetFrequencies { + if this.FactoryPresetFrequencies[i] != that1.FactoryPresetFrequencies[i] { + return false + } + } + if !this.MaxDutyCycle.Equal(that1.MaxDutyCycle) { + return false + } + if !this.Supports32BitFCnt.Equal(that1.Supports32BitFCnt) { + return false + } + if !this.UseADR.Equal(that1.UseADR) { + return false + } + if !this.ADRMargin.Equal(that1.ADRMargin) { + return false + } + if !this.ResetsFCnt.Equal(that1.ResetsFCnt) { + return false + } if this.StatusTimePeriodicity != nil && that1.StatusTimePeriodicity != nil { if *this.StatusTimePeriodicity != *that1.StatusTimePeriodicity { return false @@ -2472,25 +2685,28 @@ func (this *MACSettings) Equal(that interface{}) bool { if !this.StatusCountPeriodicity.Equal(that1.StatusCountPeriodicity) { return false } - if !this.Rx1Delay.Equal(that1.Rx1Delay) { + if !this.DesiredRx1Delay.Equal(that1.DesiredRx1Delay) { return false } - if !this.Rx2DataRateIndex.Equal(that1.Rx2DataRateIndex) { + if !this.DesiredRx1DataRateOffset.Equal(that1.DesiredRx1DataRateOffset) { return false } - if !this.Rx2Frequency.Equal(that1.Rx2Frequency) { + if !this.DesiredRx2DataRateIndex.Equal(that1.DesiredRx2DataRateIndex) { + return false + } + if this.DesiredRx2Frequency != that1.DesiredRx2Frequency { return false } return true } -func (this *MACSettings_RxDelayValue) Equal(that interface{}) bool { +func (this *MACSettings_DataRateIndexValue) Equal(that interface{}) bool { if that == nil { return this == nil } - that1, ok := that.(*MACSettings_RxDelayValue) + that1, ok := that.(*MACSettings_DataRateIndexValue) if !ok { - that2, ok := that.(MACSettings_RxDelayValue) + that2, ok := that.(MACSettings_DataRateIndexValue) if ok { that1 = &that2 } else { @@ -2507,14 +2723,14 @@ func (this *MACSettings_RxDelayValue) Equal(that interface{}) bool { } return true } -func (this *MACSettings_DataRateIndexValue) Equal(that interface{}) bool { +func (this *MACSettings_PingSlotPeriodValue) Equal(that interface{}) bool { if that == nil { return this == nil } - that1, ok := that.(*MACSettings_DataRateIndexValue) + that1, ok := that.(*MACSettings_PingSlotPeriodValue) if !ok { - that2, ok := that.(MACSettings_DataRateIndexValue) + that2, ok := that.(MACSettings_PingSlotPeriodValue) if ok { that1 = &that2 } else { @@ -2531,7 +2747,55 @@ func (this *MACSettings_DataRateIndexValue) Equal(that interface{}) bool { } return true } -func (this *MACState) Equal(that interface{}) bool { +func (this *MACSettings_AggregatedDutyCycleValue) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*MACSettings_AggregatedDutyCycleValue) + if !ok { + that2, ok := that.(MACSettings_AggregatedDutyCycleValue) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Value != that1.Value { + return false + } + return true +} +func (this *MACSettings_RxDelayValue) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*MACSettings_RxDelayValue) + if !ok { + that2, ok := that.(MACSettings_RxDelayValue) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Value != that1.Value { + return false + } + return true +} +func (this *MACState) Equal(that interface{}) bool { if that == nil { return this == nil } @@ -2715,21 +2979,12 @@ func (this *EndDevice) Equal(that interface{}) bool { if this.FrequencyPlanID != that1.FrequencyPlanID { return false } - if !this.DefaultMACParameters.Equal(that1.DefaultMACParameters) { - return false - } if this.MinFrequency != that1.MinFrequency { return false } if this.MaxFrequency != that1.MaxFrequency { return false } - if this.ResetsFCnt != that1.ResetsFCnt { - return false - } - if this.Uses32BitFCnt != that1.Uses32BitFCnt { - return false - } if this.SupportsJoin != that1.SupportsJoin { return false } @@ -3155,56 +3410,56 @@ func (m *MACParameters) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintEndDevice(dAtA, i, m.Rx2Frequency) } - if m.RejoinTimePeriodicity != 0 { + if m.MaxDutyCycle != 0 { dAtA[i] = 0x68 i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.RejoinTimePeriodicity)) + i = encodeVarintEndDevice(dAtA, i, uint64(m.MaxDutyCycle)) } - if m.RejoinCountPeriodicity != 0 { + if m.RejoinTimePeriodicity != 0 { dAtA[i] = 0x70 i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.RejoinCountPeriodicity)) + i = encodeVarintEndDevice(dAtA, i, uint64(m.RejoinTimePeriodicity)) } - if m.MaxDutyCycle != 0 { + if m.RejoinCountPeriodicity != 0 { dAtA[i] = 0x78 i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.MaxDutyCycle)) - } - if len(m.Channels) > 0 { - for _, msg := range m.Channels { - dAtA[i] = 0x82 - i++ - dAtA[i] = 0x1 - i++ - i = encodeVarintEndDevice(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } + i = encodeVarintEndDevice(dAtA, i, uint64(m.RejoinCountPeriodicity)) } if m.PingSlotFrequency != 0 { - dAtA[i] = 0x88 + dAtA[i] = 0x80 i++ dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, m.PingSlotFrequency) } if m.PingSlotDataRateIndex != 0 { - dAtA[i] = 0x90 + dAtA[i] = 0x88 i++ dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.PingSlotDataRateIndex)) } if m.BeaconFrequency != 0 { - dAtA[i] = 0x98 + dAtA[i] = 0x90 i++ dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, m.BeaconFrequency) } + if len(m.Channels) > 0 { + for _, msg := range m.Channels { + dAtA[i] = 0x9a + i++ + dAtA[i] = 0x1 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -3459,11 +3714,11 @@ func (m *EndDeviceVersion) MarshalTo(dAtA []byte) (int, error) { } i++ } - if m.DefaultMACParameters != nil { + if m.DefaultMACSettings != nil { dAtA[i] = 0x42 i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.DefaultMACParameters.Size())) - n5, err := m.DefaultMACParameters.MarshalTo(dAtA[i:]) + i = encodeVarintEndDevice(dAtA, i, uint64(m.DefaultMACSettings.Size())) + n5, err := m.DefaultMACSettings.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -3489,16 +3744,6 @@ func (m *EndDeviceVersion) MarshalTo(dAtA []byte) (int, error) { } i++ } - if m.Uses32BitFCnt { - dAtA[i] = 0x60 - i++ - if m.Uses32BitFCnt { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - } if m.SupportsJoin { dAtA[i] = 0x68 i++ @@ -3545,38 +3790,43 @@ func (m *MACSettings) MarshalTo(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.UseADR != nil { + if m.ClassBTimeout != nil { dAtA[i] = 0xa i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.UseADR.Size())) - n7, err := m.UseADR.MarshalTo(dAtA[i:]) + i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ClassBTimeout))) + n7, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.ClassBTimeout, dAtA[i:]) if err != nil { return 0, err } i += n7 } - if m.ADRMargin != nil { + if m.PingSlotPeriodicity != nil { dAtA[i] = 0x12 i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.ADRMargin.Size())) - n8, err := m.ADRMargin.MarshalTo(dAtA[i:]) + i = encodeVarintEndDevice(dAtA, i, uint64(m.PingSlotPeriodicity.Size())) + n8, err := m.PingSlotPeriodicity.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n8 } - if m.ClassBTimeout != nil { + if m.PingSlotDataRateIndex != nil { dAtA[i] = 0x1a i++ - i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ClassBTimeout))) - n9, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.ClassBTimeout, dAtA[i:]) + i = encodeVarintEndDevice(dAtA, i, uint64(m.PingSlotDataRateIndex.Size())) + n9, err := m.PingSlotDataRateIndex.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n9 } + if m.PingSlotFrequency != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintEndDevice(dAtA, i, m.PingSlotFrequency) + } if m.ClassCTimeout != nil { - dAtA[i] = 0x22 + dAtA[i] = 0x2a i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ClassCTimeout))) n10, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.ClassCTimeout, dAtA[i:]) @@ -3585,60 +3835,179 @@ func (m *MACSettings) MarshalTo(dAtA []byte) (int, error) { } i += n10 } + if m.Rx1Delay != nil { + dAtA[i] = 0x32 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.Rx1Delay.Size())) + n11, err := m.Rx1Delay.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n11 + } + if m.Rx1DataRateOffset != nil { + dAtA[i] = 0x3a + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.Rx1DataRateOffset.Size())) + n12, err := m.Rx1DataRateOffset.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n12 + } + if m.Rx2DataRateIndex != nil { + dAtA[i] = 0x42 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.Rx2DataRateIndex.Size())) + n13, err := m.Rx2DataRateIndex.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n13 + } + if m.Rx2Frequency != 0 { + dAtA[i] = 0x48 + i++ + i = encodeVarintEndDevice(dAtA, i, m.Rx2Frequency) + } + if len(m.FactoryPresetFrequencies) > 0 { + dAtA15 := make([]byte, len(m.FactoryPresetFrequencies)*10) + var j14 int + for _, num := range m.FactoryPresetFrequencies { + for num >= 1<<7 { + dAtA15[j14] = uint8(num&0x7f | 0x80) + num >>= 7 + j14++ + } + dAtA15[j14] = uint8(num) + j14++ + } + dAtA[i] = 0x52 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(j14)) + i += copy(dAtA[i:], dAtA15[:j14]) + } + if m.MaxDutyCycle != nil { + dAtA[i] = 0x5a + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.MaxDutyCycle.Size())) + n16, err := m.MaxDutyCycle.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n16 + } + if m.Supports32BitFCnt != nil { + dAtA[i] = 0x62 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.Supports32BitFCnt.Size())) + n17, err := m.Supports32BitFCnt.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n17 + } + if m.UseADR != nil { + dAtA[i] = 0x6a + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.UseADR.Size())) + n18, err := m.UseADR.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n18 + } + if m.ADRMargin != nil { + dAtA[i] = 0x72 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.ADRMargin.Size())) + n19, err := m.ADRMargin.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n19 + } + if m.ResetsFCnt != nil { + dAtA[i] = 0x7a + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.ResetsFCnt.Size())) + n20, err := m.ResetsFCnt.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n20 + } if m.StatusTimePeriodicity != nil { - dAtA[i] = 0x2a + dAtA[i] = 0x82 + i++ + dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(*m.StatusTimePeriodicity))) - n11, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.StatusTimePeriodicity, dAtA[i:]) + n21, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.StatusTimePeriodicity, dAtA[i:]) if err != nil { return 0, err } - i += n11 + i += n21 } if m.StatusCountPeriodicity != nil { - dAtA[i] = 0x32 + dAtA[i] = 0x8a + i++ + dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.StatusCountPeriodicity.Size())) - n12, err := m.StatusCountPeriodicity.MarshalTo(dAtA[i:]) + n22, err := m.StatusCountPeriodicity.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n12 + i += n22 } - if m.Rx1Delay != nil { - dAtA[i] = 0x3a + if m.DesiredRx1Delay != nil { + dAtA[i] = 0x92 i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.Rx1Delay.Size())) - n13, err := m.Rx1Delay.MarshalTo(dAtA[i:]) + dAtA[i] = 0x1 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.DesiredRx1Delay.Size())) + n23, err := m.DesiredRx1Delay.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n13 + i += n23 } - if m.Rx2DataRateIndex != nil { - dAtA[i] = 0x42 + if m.DesiredRx1DataRateOffset != nil { + dAtA[i] = 0x9a i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.Rx2DataRateIndex.Size())) - n14, err := m.Rx2DataRateIndex.MarshalTo(dAtA[i:]) + dAtA[i] = 0x1 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.DesiredRx1DataRateOffset.Size())) + n24, err := m.DesiredRx1DataRateOffset.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n14 + i += n24 } - if m.Rx2Frequency != nil { - dAtA[i] = 0x4a + if m.DesiredRx2DataRateIndex != nil { + dAtA[i] = 0xa2 i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.Rx2Frequency.Size())) - n15, err := m.Rx2Frequency.MarshalTo(dAtA[i:]) + dAtA[i] = 0x1 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.DesiredRx2DataRateIndex.Size())) + n25, err := m.DesiredRx2DataRateIndex.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n15 + i += n25 + } + if m.DesiredRx2Frequency != 0 { + dAtA[i] = 0xa8 + i++ + dAtA[i] = 0x1 + i++ + i = encodeVarintEndDevice(dAtA, i, m.DesiredRx2Frequency) } return i, nil } -func (m *MACSettings_RxDelayValue) Marshal() (dAtA []byte, err error) { +func (m *MACSettings_DataRateIndexValue) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) @@ -3648,7 +4017,7 @@ func (m *MACSettings_RxDelayValue) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MACSettings_RxDelayValue) MarshalTo(dAtA []byte) (int, error) { +func (m *MACSettings_DataRateIndexValue) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int @@ -3661,7 +4030,7 @@ func (m *MACSettings_RxDelayValue) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func (m *MACSettings_DataRateIndexValue) Marshal() (dAtA []byte, err error) { +func (m *MACSettings_PingSlotPeriodValue) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) @@ -3671,7 +4040,7 @@ func (m *MACSettings_DataRateIndexValue) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MACSettings_DataRateIndexValue) MarshalTo(dAtA []byte) (int, error) { +func (m *MACSettings_PingSlotPeriodValue) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int @@ -3684,7 +4053,7 @@ func (m *MACSettings_DataRateIndexValue) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func (m *MACState) Marshal() (dAtA []byte, err error) { +func (m *MACSettings_AggregatedDutyCycleValue) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalTo(dAtA) @@ -3694,31 +4063,77 @@ func (m *MACState) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MACState) MarshalTo(dAtA []byte) (int, error) { +func (m *MACSettings_AggregatedDutyCycleValue) MarshalTo(dAtA []byte) (int, error) { var i int _ = i var l int _ = l - dAtA[i] = 0xa - i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.CurrentParameters.Size())) - n16, err := m.CurrentParameters.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err + if m.Value != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.Value)) } - i += n16 - dAtA[i] = 0x12 - i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.DesiredParameters.Size())) - n17, err := m.DesiredParameters.MarshalTo(dAtA[i:]) + return i, nil +} + +func (m *MACSettings_RxDelayValue) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) if err != nil { - return 0, err + return nil, err } - i += n17 - if m.DeviceClass != 0 { - dAtA[i] = 0x18 - i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.DeviceClass)) + return dAtA[:n], nil +} + +func (m *MACSettings_RxDelayValue) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Value != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.Value)) + } + return i, nil +} + +func (m *MACState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MACState) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.CurrentParameters.Size())) + n26, err := m.CurrentParameters.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n26 + dAtA[i] = 0x12 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.DesiredParameters.Size())) + n27, err := m.DesiredParameters.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n27 + if m.DeviceClass != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintEndDevice(dAtA, i, uint64(m.DeviceClass)) } if m.LoRaWANVersion != 0 { dAtA[i] = 0x20 @@ -3729,11 +4144,11 @@ func (m *MACState) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastConfirmedDownlinkAt))) - n18, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastConfirmedDownlinkAt, dAtA[i:]) + n28, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastConfirmedDownlinkAt, dAtA[i:]) if err != nil { return 0, err } - i += n18 + i += n28 } if m.LastDevStatusFCntUp != 0 { dAtA[i] = 0x30 @@ -3749,11 +4164,11 @@ func (m *MACState) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x42 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.PendingApplicationDownlink.Size())) - n19, err := m.PendingApplicationDownlink.MarshalTo(dAtA[i:]) + n29, err := m.PendingApplicationDownlink.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n29 } if len(m.QueuedResponses) > 0 { for _, msg := range m.QueuedResponses { @@ -3783,21 +4198,21 @@ func (m *MACState) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x5a i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.QueuedJoinAccept.Size())) - n20, err := m.QueuedJoinAccept.MarshalTo(dAtA[i:]) + n30, err := m.QueuedJoinAccept.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n30 } if m.PendingJoinRequest != nil { dAtA[i] = 0x62 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.PendingJoinRequest.Size())) - n21, err := m.PendingJoinRequest.MarshalTo(dAtA[i:]) + n31, err := m.PendingJoinRequest.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n31 } if m.RxWindowsAvailable { dAtA[i] = 0x68 @@ -3836,19 +4251,19 @@ func (m *MACState_JoinAccept) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Request.Size())) - n22, err := m.Request.MarshalTo(dAtA[i:]) + n32, err := m.Request.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n22 + i += n32 dAtA[i] = 0x1a i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Keys.Size())) - n23, err := m.Keys.MarshalTo(dAtA[i:]) + n33, err := m.Keys.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n33 return i, nil } @@ -3870,27 +4285,27 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.EndDeviceIdentifiers.Size())) - n24, err := m.EndDeviceIdentifiers.MarshalTo(dAtA[i:]) + n34, err := m.EndDeviceIdentifiers.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n34 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.CreatedAt))) - n25, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i:]) + n35, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreatedAt, dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n35 dAtA[i] = 0x1a i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.UpdatedAt))) - n26, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.UpdatedAt, dAtA[i:]) + n36, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.UpdatedAt, dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n36 if len(m.Name) > 0 { dAtA[i] = 0x22 i++ @@ -3924,11 +4339,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x3a i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.VersionIDs.Size())) - n27, err := m.VersionIDs.MarshalTo(dAtA[i:]) + n37, err := m.VersionIDs.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n27 + i += n37 } if len(m.ServiceProfileID) > 0 { dAtA[i] = 0x42 @@ -3974,11 +4389,11 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(v.Size())) - n28, err := v.MarshalTo(dAtA[i:]) + n38, err := v.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n28 + i += n38 } } } @@ -4022,58 +4437,22 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { i = encodeVarintEndDevice(dAtA, i, uint64(len(m.FrequencyPlanID))) i += copy(dAtA[i:], m.FrequencyPlanID) } - if m.DefaultMACParameters != nil { - dAtA[i] = 0x92 - i++ - dAtA[i] = 0x1 - i++ - i = encodeVarintEndDevice(dAtA, i, uint64(m.DefaultMACParameters.Size())) - n29, err := m.DefaultMACParameters.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n29 - } if m.MinFrequency != 0 { - dAtA[i] = 0x98 + dAtA[i] = 0x90 i++ dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, m.MinFrequency) } if m.MaxFrequency != 0 { - dAtA[i] = 0xa0 + dAtA[i] = 0x98 i++ dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, m.MaxFrequency) } - if m.ResetsFCnt { - dAtA[i] = 0xa8 - i++ - dAtA[i] = 0x1 - i++ - if m.ResetsFCnt { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - } - if m.Uses32BitFCnt { - dAtA[i] = 0xb0 - i++ - dAtA[i] = 0x1 - i++ - if m.Uses32BitFCnt { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i++ - } if m.SupportsJoin { - dAtA[i] = 0xb8 + dAtA[i] = 0xa0 i++ dAtA[i] = 0x1 i++ @@ -4085,7 +4464,7 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { i++ } if m.ResetsJoinNonces { - dAtA[i] = 0xc0 + dAtA[i] = 0xa8 i++ dAtA[i] = 0x1 i++ @@ -4097,145 +4476,145 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { i++ } if m.RootKeys != nil { - dAtA[i] = 0xca + dAtA[i] = 0xb2 i++ dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.RootKeys.Size())) - n30, err := m.RootKeys.MarshalTo(dAtA[i:]) + n39, err := m.RootKeys.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n30 + i += n39 } if m.NetID != nil { - dAtA[i] = 0xd2 + dAtA[i] = 0xba i++ dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.NetID.Size())) - n31, err := m.NetID.MarshalTo(dAtA[i:]) + n40, err := m.NetID.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n31 + i += n40 } if m.MACSettings != nil { - dAtA[i] = 0xda + dAtA[i] = 0xc2 i++ dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.MACSettings.Size())) - n32, err := m.MACSettings.MarshalTo(dAtA[i:]) + n41, err := m.MACSettings.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n32 + i += n41 } if m.MACState != nil { - dAtA[i] = 0xe2 + dAtA[i] = 0xca i++ dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.MACState.Size())) - n33, err := m.MACState.MarshalTo(dAtA[i:]) + n42, err := m.MACState.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n33 + i += n42 } if m.Session != nil { - dAtA[i] = 0xea + dAtA[i] = 0xd2 i++ dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Session.Size())) - n34, err := m.Session.MarshalTo(dAtA[i:]) + n43, err := m.Session.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n34 + i += n43 } if m.PendingSession != nil { - dAtA[i] = 0xf2 + dAtA[i] = 0xda i++ dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.PendingSession.Size())) - n35, err := m.PendingSession.MarshalTo(dAtA[i:]) + n44, err := m.PendingSession.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n35 + i += n44 } if m.LastDevNonce != 0 { - dAtA[i] = 0xf8 + dAtA[i] = 0xe0 i++ dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.LastDevNonce)) } if len(m.UsedDevNonces) > 0 { - dAtA37 := make([]byte, len(m.UsedDevNonces)*10) - var j36 int + dAtA46 := make([]byte, len(m.UsedDevNonces)*10) + var j45 int for _, num := range m.UsedDevNonces { for num >= 1<<7 { - dAtA37[j36] = uint8(uint64(num)&0x7f | 0x80) + dAtA46[j45] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j36++ + j45++ } - dAtA37[j36] = uint8(num) - j36++ + dAtA46[j45] = uint8(num) + j45++ } - dAtA[i] = 0x82 + dAtA[i] = 0xea i++ - dAtA[i] = 0x2 + dAtA[i] = 0x1 i++ - i = encodeVarintEndDevice(dAtA, i, uint64(j36)) - i += copy(dAtA[i:], dAtA37[:j36]) + i = encodeVarintEndDevice(dAtA, i, uint64(j45)) + i += copy(dAtA[i:], dAtA46[:j45]) } if m.LastJoinNonce != 0 { - dAtA[i] = 0x88 + dAtA[i] = 0xf0 i++ - dAtA[i] = 0x2 + dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.LastJoinNonce)) } if m.LastRJCount0 != 0 { - dAtA[i] = 0x90 + dAtA[i] = 0xf8 i++ - dAtA[i] = 0x2 + dAtA[i] = 0x1 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.LastRJCount0)) } if m.LastRJCount1 != 0 { - dAtA[i] = 0x98 + dAtA[i] = 0x80 i++ dAtA[i] = 0x2 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.LastRJCount1)) } if m.LastDevStatusReceivedAt != nil { - dAtA[i] = 0xa2 + dAtA[i] = 0x8a i++ dAtA[i] = 0x2 i++ i = encodeVarintEndDevice(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(*m.LastDevStatusReceivedAt))) - n38, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastDevStatusReceivedAt, dAtA[i:]) + n47, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.LastDevStatusReceivedAt, dAtA[i:]) if err != nil { return 0, err } - i += n38 + i += n47 } if m.PowerState != 0 { - dAtA[i] = 0xa8 + dAtA[i] = 0x90 i++ dAtA[i] = 0x2 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.PowerState)) } if m.BatteryPercentage != 0 { - dAtA[i] = 0xb5 + dAtA[i] = 0x9d i++ dAtA[i] = 0x2 i++ @@ -4243,7 +4622,7 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { i += 4 } if m.DownlinkMargin != 0 { - dAtA[i] = 0xb8 + dAtA[i] = 0xa0 i++ dAtA[i] = 0x2 i++ @@ -4251,7 +4630,7 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { } if len(m.RecentADRUplinks) > 0 { for _, msg := range m.RecentADRUplinks { - dAtA[i] = 0xc2 + dAtA[i] = 0xaa i++ dAtA[i] = 0x2 i++ @@ -4265,7 +4644,7 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { } if len(m.RecentUplinks) > 0 { for _, msg := range m.RecentUplinks { - dAtA[i] = 0xca + dAtA[i] = 0xb2 i++ dAtA[i] = 0x2 i++ @@ -4279,7 +4658,7 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { } if len(m.RecentDownlinks) > 0 { for _, msg := range m.RecentDownlinks { - dAtA[i] = 0xd2 + dAtA[i] = 0xba i++ dAtA[i] = 0x2 i++ @@ -4293,7 +4672,7 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { } if len(m.QueuedApplicationDownlinks) > 0 { for _, msg := range m.QueuedApplicationDownlinks { - dAtA[i] = 0xda + dAtA[i] = 0xc2 i++ dAtA[i] = 0x2 i++ @@ -4306,19 +4685,19 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { } } if m.Formatters != nil { - dAtA[i] = 0xe2 + dAtA[i] = 0xca i++ dAtA[i] = 0x2 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Formatters.Size())) - n39, err := m.Formatters.MarshalTo(dAtA[i:]) + n48, err := m.Formatters.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n39 + i += n48 } if len(m.ProvisionerID) > 0 { - dAtA[i] = 0xea + dAtA[i] = 0xd2 i++ dAtA[i] = 0x2 i++ @@ -4326,16 +4705,16 @@ func (m *EndDevice) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], m.ProvisionerID) } if m.ProvisioningData != nil { - dAtA[i] = 0xf2 + dAtA[i] = 0xda i++ dAtA[i] = 0x2 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.ProvisioningData.Size())) - n40, err := m.ProvisioningData.MarshalTo(dAtA[i:]) + n49, err := m.ProvisioningData.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n40 + i += n49 } return i, nil } @@ -4388,11 +4767,11 @@ func (m *CreateEndDeviceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.EndDevice.Size())) - n41, err := m.EndDevice.MarshalTo(dAtA[i:]) + n50, err := m.EndDevice.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n41 + i += n50 return i, nil } @@ -4414,19 +4793,19 @@ func (m *UpdateEndDeviceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.EndDevice.Size())) - n42, err := m.EndDevice.MarshalTo(dAtA[i:]) + n51, err := m.EndDevice.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n42 + i += n51 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.FieldMask.Size())) - n43, err := m.FieldMask.MarshalTo(dAtA[i:]) + n52, err := m.FieldMask.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n43 + i += n52 return i, nil } @@ -4448,19 +4827,19 @@ func (m *GetEndDeviceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.EndDeviceIdentifiers.Size())) - n44, err := m.EndDeviceIdentifiers.MarshalTo(dAtA[i:]) + n53, err := m.EndDeviceIdentifiers.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n44 + i += n53 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.FieldMask.Size())) - n45, err := m.FieldMask.MarshalTo(dAtA[i:]) + n54, err := m.FieldMask.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n45 + i += n54 return i, nil } @@ -4482,19 +4861,19 @@ func (m *ListEndDevicesRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.ApplicationIdentifiers.Size())) - n46, err := m.ApplicationIdentifiers.MarshalTo(dAtA[i:]) + n55, err := m.ApplicationIdentifiers.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n46 + i += n55 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.FieldMask.Size())) - n47, err := m.FieldMask.MarshalTo(dAtA[i:]) + n56, err := m.FieldMask.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n47 + i += n56 if len(m.Order) > 0 { dAtA[i] = 0x1a i++ @@ -4532,19 +4911,19 @@ func (m *SetEndDeviceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.Device.Size())) - n48, err := m.Device.MarshalTo(dAtA[i:]) + n57, err := m.Device.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n48 + i += n57 dAtA[i] = 0x12 i++ i = encodeVarintEndDevice(dAtA, i, uint64(m.FieldMask.Size())) - n49, err := m.FieldMask.MarshalTo(dAtA[i:]) + n58, err := m.FieldMask.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n49 + i += n58 return i, nil } @@ -4613,17 +4992,48 @@ func NewPopulatedEndDeviceVersionIdentifiers(r randyEndDevice, easy bool) *EndDe func NewPopulatedMACSettings(r randyEndDevice, easy bool) *MACSettings { this := &MACSettings{} if r.Intn(10) != 0 { - this.UseADR = types.NewPopulatedBoolValue(r, easy) + this.ClassBTimeout = github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy) } if r.Intn(10) != 0 { - this.ADRMargin = types.NewPopulatedFloatValue(r, easy) + this.PingSlotPeriodicity = NewPopulatedMACSettings_PingSlotPeriodValue(r, easy) } if r.Intn(10) != 0 { - this.ClassBTimeout = github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy) + this.PingSlotDataRateIndex = NewPopulatedMACSettings_DataRateIndexValue(r, easy) } + this.PingSlotFrequency = uint64(r.Uint32()) if r.Intn(10) != 0 { this.ClassCTimeout = github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy) } + if r.Intn(10) != 0 { + this.Rx1Delay = NewPopulatedMACSettings_RxDelayValue(r, easy) + } + if r.Intn(10) != 0 { + this.Rx1DataRateOffset = types.NewPopulatedUInt32Value(r, easy) + } + if r.Intn(10) != 0 { + this.Rx2DataRateIndex = NewPopulatedMACSettings_DataRateIndexValue(r, easy) + } + this.Rx2Frequency = uint64(r.Uint32()) + v5 := r.Intn(10) + this.FactoryPresetFrequencies = make([]uint64, v5) + for i := 0; i < v5; i++ { + this.FactoryPresetFrequencies[i] = uint64(r.Uint32()) + } + if r.Intn(10) != 0 { + this.MaxDutyCycle = NewPopulatedMACSettings_AggregatedDutyCycleValue(r, easy) + } + if r.Intn(10) != 0 { + this.Supports32BitFCnt = types.NewPopulatedBoolValue(r, easy) + } + if r.Intn(10) != 0 { + this.UseADR = types.NewPopulatedBoolValue(r, easy) + } + if r.Intn(10) != 0 { + this.ADRMargin = types.NewPopulatedFloatValue(r, easy) + } + if r.Intn(10) != 0 { + this.ResetsFCnt = types.NewPopulatedBoolValue(r, easy) + } if r.Intn(10) != 0 { this.StatusTimePeriodicity = github_com_gogo_protobuf_types.NewPopulatedStdDuration(r, easy) } @@ -4631,30 +5041,47 @@ func NewPopulatedMACSettings(r randyEndDevice, easy bool) *MACSettings { this.StatusCountPeriodicity = types.NewPopulatedUInt32Value(r, easy) } if r.Intn(10) != 0 { - this.Rx1Delay = NewPopulatedMACSettings_RxDelayValue(r, easy) + this.DesiredRx1Delay = NewPopulatedMACSettings_RxDelayValue(r, easy) } if r.Intn(10) != 0 { - this.Rx2DataRateIndex = NewPopulatedMACSettings_DataRateIndexValue(r, easy) + this.DesiredRx1DataRateOffset = types.NewPopulatedUInt32Value(r, easy) } if r.Intn(10) != 0 { - this.Rx2Frequency = types.NewPopulatedUInt64Value(r, easy) + this.DesiredRx2DataRateIndex = NewPopulatedMACSettings_DataRateIndexValue(r, easy) } + this.DesiredRx2Frequency = uint64(r.Uint32()) if !easy && r.Intn(10) != 0 { } return this } -func NewPopulatedMACSettings_RxDelayValue(r randyEndDevice, easy bool) *MACSettings_RxDelayValue { - this := &MACSettings_RxDelayValue{} - this.Value = RxDelay([]int32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}[r.Intn(16)]) +func NewPopulatedMACSettings_DataRateIndexValue(r randyEndDevice, easy bool) *MACSettings_DataRateIndexValue { + this := &MACSettings_DataRateIndexValue{} + this.Value = DataRateIndex([]int32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}[r.Intn(16)]) if !easy && r.Intn(10) != 0 { } return this } -func NewPopulatedMACSettings_DataRateIndexValue(r randyEndDevice, easy bool) *MACSettings_DataRateIndexValue { - this := &MACSettings_DataRateIndexValue{} - this.Value = DataRateIndex([]int32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}[r.Intn(16)]) +func NewPopulatedMACSettings_PingSlotPeriodValue(r randyEndDevice, easy bool) *MACSettings_PingSlotPeriodValue { + this := &MACSettings_PingSlotPeriodValue{} + this.Value = PingSlotPeriod([]int32{0, 1, 2, 3, 4, 5, 6, 7}[r.Intn(8)]) + if !easy && r.Intn(10) != 0 { + } + return this +} + +func NewPopulatedMACSettings_AggregatedDutyCycleValue(r randyEndDevice, easy bool) *MACSettings_AggregatedDutyCycleValue { + this := &MACSettings_AggregatedDutyCycleValue{} + this.Value = AggregatedDutyCycle([]int32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}[r.Intn(16)]) + if !easy && r.Intn(10) != 0 { + } + return this +} + +func NewPopulatedMACSettings_RxDelayValue(r randyEndDevice, easy bool) *MACSettings_RxDelayValue { + this := &MACSettings_RxDelayValue{} + this.Value = RxDelay([]int32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}[r.Intn(16)]) if !easy && r.Intn(10) != 0 { } return this @@ -4662,15 +5089,15 @@ func NewPopulatedMACSettings_DataRateIndexValue(r randyEndDevice, easy bool) *MA func NewPopulatedMACState_JoinAccept(r randyEndDevice, easy bool) *MACState_JoinAccept { this := &MACState_JoinAccept{} - v5 := r.Intn(100) - this.Payload = make([]byte, v5) - for i := 0; i < v5; i++ { + v6 := r.Intn(100) + this.Payload = make([]byte, v6) + for i := 0; i < v6; i++ { this.Payload[i] = byte(r.Intn(256)) } - v6 := NewPopulatedJoinRequest(r, easy) - this.Request = *v6 - v7 := NewPopulatedSessionKeys(r, easy) - this.Keys = *v7 + v7 := NewPopulatedJoinRequest(r, easy) + this.Request = *v7 + v8 := NewPopulatedSessionKeys(r, easy) + this.Keys = *v8 if !easy && r.Intn(10) != 0 { } return this @@ -4679,9 +5106,9 @@ func NewPopulatedMACState_JoinAccept(r randyEndDevice, easy bool) *MACState_Join func NewPopulatedEndDevices(r randyEndDevice, easy bool) *EndDevices { this := &EndDevices{} if r.Intn(10) != 0 { - v8 := r.Intn(5) - this.EndDevices = make([]*EndDevice, v8) - for i := 0; i < v8; i++ { + v9 := r.Intn(5) + this.EndDevices = make([]*EndDevice, v9) + for i := 0; i < v9; i++ { this.EndDevices[i] = NewPopulatedEndDevice(r, easy) } } @@ -4692,8 +5119,8 @@ func NewPopulatedEndDevices(r randyEndDevice, easy bool) *EndDevices { func NewPopulatedCreateEndDeviceRequest(r randyEndDevice, easy bool) *CreateEndDeviceRequest { this := &CreateEndDeviceRequest{} - v9 := NewPopulatedEndDevice(r, easy) - this.EndDevice = *v9 + v10 := NewPopulatedEndDevice(r, easy) + this.EndDevice = *v10 if !easy && r.Intn(10) != 0 { } return this @@ -4701,10 +5128,10 @@ func NewPopulatedCreateEndDeviceRequest(r randyEndDevice, easy bool) *CreateEndD func NewPopulatedUpdateEndDeviceRequest(r randyEndDevice, easy bool) *UpdateEndDeviceRequest { this := &UpdateEndDeviceRequest{} - v10 := NewPopulatedEndDevice(r, easy) - this.EndDevice = *v10 - v11 := types.NewPopulatedFieldMask(r, easy) - this.FieldMask = *v11 + v11 := NewPopulatedEndDevice(r, easy) + this.EndDevice = *v11 + v12 := types.NewPopulatedFieldMask(r, easy) + this.FieldMask = *v12 if !easy && r.Intn(10) != 0 { } return this @@ -4712,10 +5139,10 @@ func NewPopulatedUpdateEndDeviceRequest(r randyEndDevice, easy bool) *UpdateEndD func NewPopulatedGetEndDeviceRequest(r randyEndDevice, easy bool) *GetEndDeviceRequest { this := &GetEndDeviceRequest{} - v12 := NewPopulatedEndDeviceIdentifiers(r, easy) - this.EndDeviceIdentifiers = *v12 - v13 := types.NewPopulatedFieldMask(r, easy) - this.FieldMask = *v13 + v13 := NewPopulatedEndDeviceIdentifiers(r, easy) + this.EndDeviceIdentifiers = *v13 + v14 := types.NewPopulatedFieldMask(r, easy) + this.FieldMask = *v14 if !easy && r.Intn(10) != 0 { } return this @@ -4723,10 +5150,10 @@ func NewPopulatedGetEndDeviceRequest(r randyEndDevice, easy bool) *GetEndDeviceR func NewPopulatedListEndDevicesRequest(r randyEndDevice, easy bool) *ListEndDevicesRequest { this := &ListEndDevicesRequest{} - v14 := NewPopulatedApplicationIdentifiers(r, easy) - this.ApplicationIdentifiers = *v14 - v15 := types.NewPopulatedFieldMask(r, easy) - this.FieldMask = *v15 + v15 := NewPopulatedApplicationIdentifiers(r, easy) + this.ApplicationIdentifiers = *v15 + v16 := types.NewPopulatedFieldMask(r, easy) + this.FieldMask = *v16 this.Order = randStringEndDevice(r) this.Limit = r.Uint32() this.Page = r.Uint32() @@ -4737,10 +5164,10 @@ func NewPopulatedListEndDevicesRequest(r randyEndDevice, easy bool) *ListEndDevi func NewPopulatedSetEndDeviceRequest(r randyEndDevice, easy bool) *SetEndDeviceRequest { this := &SetEndDeviceRequest{} - v16 := NewPopulatedEndDevice(r, easy) - this.Device = *v16 - v17 := types.NewPopulatedFieldMask(r, easy) - this.FieldMask = *v17 + v17 := NewPopulatedEndDevice(r, easy) + this.Device = *v17 + v18 := types.NewPopulatedFieldMask(r, easy) + this.FieldMask = *v18 if !easy && r.Intn(10) != 0 { } return this @@ -4765,9 +5192,9 @@ func randUTF8RuneEndDevice(r randyEndDevice) rune { return rune(ru + 61) } func randStringEndDevice(r randyEndDevice) string { - v18 := r.Intn(100) - tmps := make([]rune, v18) - for i := 0; i < v18; i++ { + v19 := r.Intn(100) + tmps := make([]rune, v19) + for i := 0; i < v19; i++ { tmps[i] = randUTF8RuneEndDevice(r) } return string(tmps) @@ -4789,11 +5216,11 @@ func randFieldEndDevice(dAtA []byte, r randyEndDevice, fieldNumber int, wire int switch wire { case 0: dAtA = encodeVarintPopulateEndDevice(dAtA, uint64(key)) - v19 := r.Int63() + v20 := r.Int63() if r.Intn(2) == 0 { - v19 *= -1 + v20 *= -1 } - dAtA = encodeVarintPopulateEndDevice(dAtA, uint64(v19)) + dAtA = encodeVarintPopulateEndDevice(dAtA, uint64(v20)) case 1: dAtA = encodeVarintPopulateEndDevice(dAtA, uint64(key)) dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) @@ -4887,21 +5314,15 @@ func (m *MACParameters) Size() (n int) { if m.Rx2Frequency != 0 { n += 1 + sovEndDevice(m.Rx2Frequency) } + if m.MaxDutyCycle != 0 { + n += 1 + sovEndDevice(uint64(m.MaxDutyCycle)) + } if m.RejoinTimePeriodicity != 0 { n += 1 + sovEndDevice(uint64(m.RejoinTimePeriodicity)) } if m.RejoinCountPeriodicity != 0 { n += 1 + sovEndDevice(uint64(m.RejoinCountPeriodicity)) } - if m.MaxDutyCycle != 0 { - n += 1 + sovEndDevice(uint64(m.MaxDutyCycle)) - } - if len(m.Channels) > 0 { - for _, e := range m.Channels { - l = e.Size() - n += 2 + l + sovEndDevice(uint64(l)) - } - } if m.PingSlotFrequency != 0 { n += 2 + sovEndDevice(m.PingSlotFrequency) } @@ -4911,6 +5332,12 @@ func (m *MACParameters) Size() (n int) { if m.BeaconFrequency != 0 { n += 2 + sovEndDevice(m.BeaconFrequency) } + if len(m.Channels) > 0 { + for _, e := range m.Channels { + l = e.Size() + n += 2 + l + sovEndDevice(uint64(l)) + } + } return n } @@ -5041,8 +5468,8 @@ func (m *EndDeviceVersion) Size() (n int) { if m.SupportsClassC { n += 2 } - if m.DefaultMACParameters != nil { - l = m.DefaultMACParameters.Size() + if m.DefaultMACSettings != nil { + l = m.DefaultMACSettings.Size() n += 1 + l + sovEndDevice(uint64(l)) } if m.MinFrequency != 0 { @@ -5054,9 +5481,6 @@ func (m *EndDeviceVersion) Size() (n int) { if m.ResetsFCnt { n += 2 } - if m.Uses32BitFCnt { - n += 2 - } if m.SupportsJoin { n += 2 } @@ -5074,67 +5498,139 @@ func (m *MACSettings) Size() (n int) { } var l int _ = l - if m.UseADR != nil { - l = m.UseADR.Size() - n += 1 + l + sovEndDevice(uint64(l)) - } - if m.ADRMargin != nil { - l = m.ADRMargin.Size() - n += 1 + l + sovEndDevice(uint64(l)) - } if m.ClassBTimeout != nil { l = github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ClassBTimeout) n += 1 + l + sovEndDevice(uint64(l)) } - if m.ClassCTimeout != nil { - l = github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ClassCTimeout) + if m.PingSlotPeriodicity != nil { + l = m.PingSlotPeriodicity.Size() n += 1 + l + sovEndDevice(uint64(l)) } - if m.StatusTimePeriodicity != nil { - l = github_com_gogo_protobuf_types.SizeOfStdDuration(*m.StatusTimePeriodicity) + if m.PingSlotDataRateIndex != nil { + l = m.PingSlotDataRateIndex.Size() n += 1 + l + sovEndDevice(uint64(l)) } - if m.StatusCountPeriodicity != nil { - l = m.StatusCountPeriodicity.Size() + if m.PingSlotFrequency != 0 { + n += 1 + sovEndDevice(m.PingSlotFrequency) + } + if m.ClassCTimeout != nil { + l = github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ClassCTimeout) n += 1 + l + sovEndDevice(uint64(l)) } if m.Rx1Delay != nil { l = m.Rx1Delay.Size() n += 1 + l + sovEndDevice(uint64(l)) } + if m.Rx1DataRateOffset != nil { + l = m.Rx1DataRateOffset.Size() + n += 1 + l + sovEndDevice(uint64(l)) + } if m.Rx2DataRateIndex != nil { l = m.Rx2DataRateIndex.Size() n += 1 + l + sovEndDevice(uint64(l)) } - if m.Rx2Frequency != nil { - l = m.Rx2Frequency.Size() - n += 1 + l + sovEndDevice(uint64(l)) + if m.Rx2Frequency != 0 { + n += 1 + sovEndDevice(m.Rx2Frequency) } - return n -} - -func (m *MACSettings_RxDelayValue) Size() (n int) { - if m == nil { - return 0 + if len(m.FactoryPresetFrequencies) > 0 { + l = 0 + for _, e := range m.FactoryPresetFrequencies { + l += sovEndDevice(e) + } + n += 1 + sovEndDevice(uint64(l)) + l } - var l int - _ = l - if m.Value != 0 { - n += 1 + sovEndDevice(uint64(m.Value)) + if m.MaxDutyCycle != nil { + l = m.MaxDutyCycle.Size() + n += 1 + l + sovEndDevice(uint64(l)) } - return n -} - -func (m *MACSettings_DataRateIndexValue) Size() (n int) { - if m == nil { - return 0 + if m.Supports32BitFCnt != nil { + l = m.Supports32BitFCnt.Size() + n += 1 + l + sovEndDevice(uint64(l)) } - var l int - _ = l - if m.Value != 0 { - n += 1 + sovEndDevice(uint64(m.Value)) + if m.UseADR != nil { + l = m.UseADR.Size() + n += 1 + l + sovEndDevice(uint64(l)) } - return n + if m.ADRMargin != nil { + l = m.ADRMargin.Size() + n += 1 + l + sovEndDevice(uint64(l)) + } + if m.ResetsFCnt != nil { + l = m.ResetsFCnt.Size() + n += 1 + l + sovEndDevice(uint64(l)) + } + if m.StatusTimePeriodicity != nil { + l = github_com_gogo_protobuf_types.SizeOfStdDuration(*m.StatusTimePeriodicity) + n += 2 + l + sovEndDevice(uint64(l)) + } + if m.StatusCountPeriodicity != nil { + l = m.StatusCountPeriodicity.Size() + n += 2 + l + sovEndDevice(uint64(l)) + } + if m.DesiredRx1Delay != nil { + l = m.DesiredRx1Delay.Size() + n += 2 + l + sovEndDevice(uint64(l)) + } + if m.DesiredRx1DataRateOffset != nil { + l = m.DesiredRx1DataRateOffset.Size() + n += 2 + l + sovEndDevice(uint64(l)) + } + if m.DesiredRx2DataRateIndex != nil { + l = m.DesiredRx2DataRateIndex.Size() + n += 2 + l + sovEndDevice(uint64(l)) + } + if m.DesiredRx2Frequency != 0 { + n += 2 + sovEndDevice(m.DesiredRx2Frequency) + } + return n +} + +func (m *MACSettings_DataRateIndexValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Value != 0 { + n += 1 + sovEndDevice(uint64(m.Value)) + } + return n +} + +func (m *MACSettings_PingSlotPeriodValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Value != 0 { + n += 1 + sovEndDevice(uint64(m.Value)) + } + return n +} + +func (m *MACSettings_AggregatedDutyCycleValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Value != 0 { + n += 1 + sovEndDevice(uint64(m.Value)) + } + return n +} + +func (m *MACSettings_RxDelayValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Value != 0 { + n += 1 + sovEndDevice(uint64(m.Value)) + } + return n } func (m *MACState) Size() (n int) { @@ -5287,22 +5783,12 @@ func (m *EndDevice) Size() (n int) { if l > 0 { n += 2 + l + sovEndDevice(uint64(l)) } - if m.DefaultMACParameters != nil { - l = m.DefaultMACParameters.Size() - n += 2 + l + sovEndDevice(uint64(l)) - } if m.MinFrequency != 0 { n += 2 + sovEndDevice(m.MinFrequency) } if m.MaxFrequency != 0 { n += 2 + sovEndDevice(m.MaxFrequency) } - if m.ResetsFCnt { - n += 3 - } - if m.Uses32BitFCnt { - n += 3 - } if m.SupportsJoin { n += 3 } @@ -5538,13 +6024,13 @@ func (this *MACParameters) String() string { `Rx1DataRateOffset:` + fmt.Sprintf("%v", this.Rx1DataRateOffset) + `,`, `Rx2DataRateIndex:` + fmt.Sprintf("%v", this.Rx2DataRateIndex) + `,`, `Rx2Frequency:` + fmt.Sprintf("%v", this.Rx2Frequency) + `,`, + `MaxDutyCycle:` + fmt.Sprintf("%v", this.MaxDutyCycle) + `,`, `RejoinTimePeriodicity:` + fmt.Sprintf("%v", this.RejoinTimePeriodicity) + `,`, `RejoinCountPeriodicity:` + fmt.Sprintf("%v", this.RejoinCountPeriodicity) + `,`, - `MaxDutyCycle:` + fmt.Sprintf("%v", this.MaxDutyCycle) + `,`, - `Channels:` + strings.Replace(fmt.Sprintf("%v", this.Channels), "MACParameters_Channel", "MACParameters_Channel", 1) + `,`, `PingSlotFrequency:` + fmt.Sprintf("%v", this.PingSlotFrequency) + `,`, `PingSlotDataRateIndex:` + fmt.Sprintf("%v", this.PingSlotDataRateIndex) + `,`, `BeaconFrequency:` + fmt.Sprintf("%v", this.BeaconFrequency) + `,`, + `Channels:` + strings.Replace(fmt.Sprintf("%v", this.Channels), "MACParameters_Channel", "MACParameters_Channel", 1) + `,`, `}`, }, "") return s @@ -5613,11 +6099,10 @@ func (this *EndDeviceVersion) String() string { `Photos:` + fmt.Sprintf("%v", this.Photos) + `,`, `SupportsClassB:` + fmt.Sprintf("%v", this.SupportsClassB) + `,`, `SupportsClassC:` + fmt.Sprintf("%v", this.SupportsClassC) + `,`, - `DefaultMACParameters:` + strings.Replace(fmt.Sprintf("%v", this.DefaultMACParameters), "MACParameters", "MACParameters", 1) + `,`, + `DefaultMACSettings:` + strings.Replace(fmt.Sprintf("%v", this.DefaultMACSettings), "MACSettings", "MACSettings", 1) + `,`, `MinFrequency:` + fmt.Sprintf("%v", this.MinFrequency) + `,`, `MaxFrequency:` + fmt.Sprintf("%v", this.MaxFrequency) + `,`, `ResetsFCnt:` + fmt.Sprintf("%v", this.ResetsFCnt) + `,`, - `Uses32BitFCnt:` + fmt.Sprintf("%v", this.Uses32BitFCnt) + `,`, `SupportsJoin:` + fmt.Sprintf("%v", this.SupportsJoin) + `,`, `ResetsJoinNonces:` + fmt.Sprintf("%v", this.ResetsJoinNonces) + `,`, `DefaultFormatters:` + strings.Replace(strings.Replace(this.DefaultFormatters.String(), "MessagePayloadFormatters", "MessagePayloadFormatters", 1), `&`, ``, 1) + `,`, @@ -5630,34 +6115,66 @@ func (this *MACSettings) String() string { return "nil" } s := strings.Join([]string{`&MACSettings{`, - `UseADR:` + strings.Replace(fmt.Sprintf("%v", this.UseADR), "BoolValue", "types.BoolValue", 1) + `,`, - `ADRMargin:` + strings.Replace(fmt.Sprintf("%v", this.ADRMargin), "FloatValue", "types.FloatValue", 1) + `,`, `ClassBTimeout:` + strings.Replace(fmt.Sprintf("%v", this.ClassBTimeout), "Duration", "types.Duration", 1) + `,`, + `PingSlotPeriodicity:` + strings.Replace(fmt.Sprintf("%v", this.PingSlotPeriodicity), "MACSettings_PingSlotPeriodValue", "MACSettings_PingSlotPeriodValue", 1) + `,`, + `PingSlotDataRateIndex:` + strings.Replace(fmt.Sprintf("%v", this.PingSlotDataRateIndex), "MACSettings_DataRateIndexValue", "MACSettings_DataRateIndexValue", 1) + `,`, + `PingSlotFrequency:` + fmt.Sprintf("%v", this.PingSlotFrequency) + `,`, `ClassCTimeout:` + strings.Replace(fmt.Sprintf("%v", this.ClassCTimeout), "Duration", "types.Duration", 1) + `,`, - `StatusTimePeriodicity:` + strings.Replace(fmt.Sprintf("%v", this.StatusTimePeriodicity), "Duration", "types.Duration", 1) + `,`, - `StatusCountPeriodicity:` + strings.Replace(fmt.Sprintf("%v", this.StatusCountPeriodicity), "UInt32Value", "types.UInt32Value", 1) + `,`, `Rx1Delay:` + strings.Replace(fmt.Sprintf("%v", this.Rx1Delay), "MACSettings_RxDelayValue", "MACSettings_RxDelayValue", 1) + `,`, + `Rx1DataRateOffset:` + strings.Replace(fmt.Sprintf("%v", this.Rx1DataRateOffset), "UInt32Value", "types.UInt32Value", 1) + `,`, `Rx2DataRateIndex:` + strings.Replace(fmt.Sprintf("%v", this.Rx2DataRateIndex), "MACSettings_DataRateIndexValue", "MACSettings_DataRateIndexValue", 1) + `,`, - `Rx2Frequency:` + strings.Replace(fmt.Sprintf("%v", this.Rx2Frequency), "UInt64Value", "types.UInt64Value", 1) + `,`, + `Rx2Frequency:` + fmt.Sprintf("%v", this.Rx2Frequency) + `,`, + `FactoryPresetFrequencies:` + fmt.Sprintf("%v", this.FactoryPresetFrequencies) + `,`, + `MaxDutyCycle:` + strings.Replace(fmt.Sprintf("%v", this.MaxDutyCycle), "MACSettings_AggregatedDutyCycleValue", "MACSettings_AggregatedDutyCycleValue", 1) + `,`, + `Supports32BitFCnt:` + strings.Replace(fmt.Sprintf("%v", this.Supports32BitFCnt), "BoolValue", "types.BoolValue", 1) + `,`, + `UseADR:` + strings.Replace(fmt.Sprintf("%v", this.UseADR), "BoolValue", "types.BoolValue", 1) + `,`, + `ADRMargin:` + strings.Replace(fmt.Sprintf("%v", this.ADRMargin), "FloatValue", "types.FloatValue", 1) + `,`, + `ResetsFCnt:` + strings.Replace(fmt.Sprintf("%v", this.ResetsFCnt), "BoolValue", "types.BoolValue", 1) + `,`, + `StatusTimePeriodicity:` + strings.Replace(fmt.Sprintf("%v", this.StatusTimePeriodicity), "Duration", "types.Duration", 1) + `,`, + `StatusCountPeriodicity:` + strings.Replace(fmt.Sprintf("%v", this.StatusCountPeriodicity), "UInt32Value", "types.UInt32Value", 1) + `,`, + `DesiredRx1Delay:` + strings.Replace(fmt.Sprintf("%v", this.DesiredRx1Delay), "MACSettings_RxDelayValue", "MACSettings_RxDelayValue", 1) + `,`, + `DesiredRx1DataRateOffset:` + strings.Replace(fmt.Sprintf("%v", this.DesiredRx1DataRateOffset), "UInt32Value", "types.UInt32Value", 1) + `,`, + `DesiredRx2DataRateIndex:` + strings.Replace(fmt.Sprintf("%v", this.DesiredRx2DataRateIndex), "MACSettings_DataRateIndexValue", "MACSettings_DataRateIndexValue", 1) + `,`, + `DesiredRx2Frequency:` + fmt.Sprintf("%v", this.DesiredRx2Frequency) + `,`, `}`, }, "") return s } -func (this *MACSettings_RxDelayValue) String() string { +func (this *MACSettings_DataRateIndexValue) String() string { if this == nil { return "nil" } - s := strings.Join([]string{`&MACSettings_RxDelayValue{`, + s := strings.Join([]string{`&MACSettings_DataRateIndexValue{`, `Value:` + fmt.Sprintf("%v", this.Value) + `,`, `}`, }, "") return s } -func (this *MACSettings_DataRateIndexValue) String() string { +func (this *MACSettings_PingSlotPeriodValue) String() string { if this == nil { return "nil" } - s := strings.Join([]string{`&MACSettings_DataRateIndexValue{`, + s := strings.Join([]string{`&MACSettings_PingSlotPeriodValue{`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `}`, + }, "") + return s +} +func (this *MACSettings_AggregatedDutyCycleValue) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MACSettings_AggregatedDutyCycleValue{`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `}`, + }, "") + return s +} +func (this *MACSettings_RxDelayValue) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MACSettings_RxDelayValue{`, `Value:` + fmt.Sprintf("%v", this.Value) + `,`, `}`, }, "") @@ -5739,11 +6256,8 @@ func (this *EndDevice) String() string { `LoRaWANVersion:` + fmt.Sprintf("%v", this.LoRaWANVersion) + `,`, `LoRaWANPHYVersion:` + fmt.Sprintf("%v", this.LoRaWANPHYVersion) + `,`, `FrequencyPlanID:` + fmt.Sprintf("%v", this.FrequencyPlanID) + `,`, - `DefaultMACParameters:` + strings.Replace(fmt.Sprintf("%v", this.DefaultMACParameters), "MACParameters", "MACParameters", 1) + `,`, `MinFrequency:` + fmt.Sprintf("%v", this.MinFrequency) + `,`, `MaxFrequency:` + fmt.Sprintf("%v", this.MaxFrequency) + `,`, - `ResetsFCnt:` + fmt.Sprintf("%v", this.ResetsFCnt) + `,`, - `Uses32BitFCnt:` + fmt.Sprintf("%v", this.Uses32BitFCnt) + `,`, `SupportsJoin:` + fmt.Sprintf("%v", this.SupportsJoin) + `,`, `ResetsJoinNonces:` + fmt.Sprintf("%v", this.ResetsJoinNonces) + `,`, `RootKeys:` + strings.Replace(fmt.Sprintf("%v", this.RootKeys), "RootKeys", "RootKeys", 1) + `,`, @@ -6316,9 +6830,9 @@ func (m *MACParameters) Unmarshal(dAtA []byte) error { } case 13: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RejoinTimePeriodicity", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MaxDutyCycle", wireType) } - m.RejoinTimePeriodicity = 0 + m.MaxDutyCycle = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEndDevice @@ -6328,16 +6842,16 @@ func (m *MACParameters) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.RejoinTimePeriodicity |= (RejoinTimeExponent(b) & 0x7F) << shift + m.MaxDutyCycle |= (AggregatedDutyCycle(b) & 0x7F) << shift if b < 0x80 { break } } case 14: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RejoinCountPeriodicity", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RejoinTimePeriodicity", wireType) } - m.RejoinCountPeriodicity = 0 + m.RejoinTimePeriodicity = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEndDevice @@ -6347,16 +6861,16 @@ func (m *MACParameters) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.RejoinCountPeriodicity |= (RejoinCountExponent(b) & 0x7F) << shift + m.RejoinTimePeriodicity |= (RejoinTimeExponent(b) & 0x7F) << shift if b < 0x80 { break } } case 15: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxDutyCycle", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RejoinCountPeriodicity", wireType) } - m.MaxDutyCycle = 0 + m.RejoinCountPeriodicity = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEndDevice @@ -6366,16 +6880,16 @@ func (m *MACParameters) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.MaxDutyCycle |= (AggregatedDutyCycle(b) & 0x7F) << shift + m.RejoinCountPeriodicity |= (RejoinCountExponent(b) & 0x7F) << shift if b < 0x80 { break } } case 16: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Channels", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PingSlotFrequency", wireType) } - var msglen int + m.PingSlotFrequency = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEndDevice @@ -6385,28 +6899,16 @@ func (m *MACParameters) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= (int(b) & 0x7F) << shift + m.PingSlotFrequency |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthEndDevice - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Channels = append(m.Channels, &MACParameters_Channel{}) - if err := m.Channels[len(m.Channels)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 17: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field PingSlotFrequency", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PingSlotDataRateIndex", wireType) } - m.PingSlotFrequency = 0 + m.PingSlotDataRateIndex = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEndDevice @@ -6416,16 +6918,16 @@ func (m *MACParameters) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.PingSlotFrequency |= (uint64(b) & 0x7F) << shift + m.PingSlotDataRateIndex |= (DataRateIndex(b) & 0x7F) << shift if b < 0x80 { break } } case 18: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field PingSlotDataRateIndex", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BeaconFrequency", wireType) } - m.PingSlotDataRateIndex = 0 + m.BeaconFrequency = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEndDevice @@ -6435,16 +6937,16 @@ func (m *MACParameters) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.PingSlotDataRateIndex |= (DataRateIndex(b) & 0x7F) << shift + m.BeaconFrequency |= (uint64(b) & 0x7F) << shift if b < 0x80 { break } } case 19: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BeaconFrequency", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Channels", wireType) } - m.BeaconFrequency = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEndDevice @@ -6454,11 +6956,23 @@ func (m *MACParameters) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.BeaconFrequency |= (uint64(b) & 0x7F) << shift + msglen |= (int(b) & 0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Channels = append(m.Channels, &MACParameters_Channel{}) + if err := m.Channels[len(m.Channels)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEndDevice(dAtA[iNdEx:]) @@ -7292,7 +7806,7 @@ func (m *EndDeviceVersion) Unmarshal(dAtA []byte) error { m.SupportsClassC = bool(v != 0) case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DefaultMACParameters", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DefaultMACSettings", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -7316,10 +7830,10 @@ func (m *EndDeviceVersion) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.DefaultMACParameters == nil { - m.DefaultMACParameters = &MACParameters{} + if m.DefaultMACSettings == nil { + m.DefaultMACSettings = &MACSettings{} } - if err := m.DefaultMACParameters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.DefaultMACSettings.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -7381,26 +7895,6 @@ func (m *EndDeviceVersion) Unmarshal(dAtA []byte) error { } } m.ResetsFCnt = bool(v != 0) - case 12: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Uses32BitFCnt", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEndDevice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Uses32BitFCnt = bool(v != 0) case 13: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SupportsJoin", wireType) @@ -7523,7 +8017,7 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UseADR", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ClassBTimeout", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -7547,16 +8041,16 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.UseADR == nil { - m.UseADR = &types.BoolValue{} + if m.ClassBTimeout == nil { + m.ClassBTimeout = new(time.Duration) } - if err := m.UseADR.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(m.ClassBTimeout, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ADRMargin", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PingSlotPeriodicity", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -7580,16 +8074,16 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ADRMargin == nil { - m.ADRMargin = &types.FloatValue{} + if m.PingSlotPeriodicity == nil { + m.PingSlotPeriodicity = &MACSettings_PingSlotPeriodValue{} } - if err := m.ADRMargin.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.PingSlotPeriodicity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClassBTimeout", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PingSlotDataRateIndex", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -7613,14 +8107,33 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ClassBTimeout == nil { - m.ClassBTimeout = new(time.Duration) + if m.PingSlotDataRateIndex == nil { + m.PingSlotDataRateIndex = &MACSettings_DataRateIndexValue{} } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(m.ClassBTimeout, dAtA[iNdEx:postIndex]); err != nil { + if err := m.PingSlotDataRateIndex.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PingSlotFrequency", wireType) + } + m.PingSlotFrequency = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PingSlotFrequency |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ClassCTimeout", wireType) } @@ -7653,9 +8166,9 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StatusTimePeriodicity", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Rx1Delay", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -7679,16 +8192,16 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.StatusTimePeriodicity == nil { - m.StatusTimePeriodicity = new(time.Duration) + if m.Rx1Delay == nil { + m.Rx1Delay = &MACSettings_RxDelayValue{} } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(m.StatusTimePeriodicity, dAtA[iNdEx:postIndex]); err != nil { + if err := m.Rx1Delay.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 6: + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StatusCountPeriodicity", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Rx1DataRateOffset", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -7712,16 +8225,273 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.StatusCountPeriodicity == nil { - m.StatusCountPeriodicity = &types.UInt32Value{} + if m.Rx1DataRateOffset == nil { + m.Rx1DataRateOffset = &types.UInt32Value{} } - if err := m.StatusCountPeriodicity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Rx1DataRateOffset.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 7: + case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rx1Delay", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Rx2DataRateIndex", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Rx2DataRateIndex == nil { + m.Rx2DataRateIndex = &MACSettings_DataRateIndexValue{} + } + if err := m.Rx2DataRateIndex.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Rx2Frequency", wireType) + } + m.Rx2Frequency = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Rx2Frequency |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 10: + if wireType == 0 { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.FactoryPresetFrequencies = append(m.FactoryPresetFrequencies, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + packedLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.FactoryPresetFrequencies) == 0 { + m.FactoryPresetFrequencies = make([]uint64, 0, elementCount) + } + for iNdEx < postIndex { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.FactoryPresetFrequencies = append(m.FactoryPresetFrequencies, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field FactoryPresetFrequencies", wireType) + } + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxDutyCycle", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.MaxDutyCycle == nil { + m.MaxDutyCycle = &MACSettings_AggregatedDutyCycleValue{} + } + if err := m.MaxDutyCycle.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Supports32BitFCnt", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Supports32BitFCnt == nil { + m.Supports32BitFCnt = &types.BoolValue{} + } + if err := m.Supports32BitFCnt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UseADR", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.UseADR == nil { + m.UseADR = &types.BoolValue{} + } + if err := m.UseADR.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ADRMargin", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ADRMargin == nil { + m.ADRMargin = &types.FloatValue{} + } + if err := m.ADRMargin.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResetsFCnt", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -7738,25 +8508,259 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { break } } - if msglen < 0 { + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ResetsFCnt == nil { + m.ResetsFCnt = &types.BoolValue{} + } + if err := m.ResetsFCnt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 16: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StatusTimePeriodicity", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.StatusTimePeriodicity == nil { + m.StatusTimePeriodicity = new(time.Duration) + } + if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(m.StatusTimePeriodicity, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 17: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StatusCountPeriodicity", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.StatusCountPeriodicity == nil { + m.StatusCountPeriodicity = &types.UInt32Value{} + } + if err := m.StatusCountPeriodicity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 18: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DesiredRx1Delay", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.DesiredRx1Delay == nil { + m.DesiredRx1Delay = &MACSettings_RxDelayValue{} + } + if err := m.DesiredRx1Delay.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 19: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DesiredRx1DataRateOffset", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.DesiredRx1DataRateOffset == nil { + m.DesiredRx1DataRateOffset = &types.UInt32Value{} + } + if err := m.DesiredRx1DataRateOffset.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 20: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DesiredRx2DataRateIndex", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEndDevice + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.DesiredRx2DataRateIndex == nil { + m.DesiredRx2DataRateIndex = &MACSettings_DataRateIndexValue{} + } + if err := m.DesiredRx2DataRateIndex.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 21: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DesiredRx2Frequency", wireType) + } + m.DesiredRx2Frequency = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DesiredRx2Frequency |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipEndDevice(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { return ErrInvalidLengthEndDevice } - postIndex := iNdEx + msglen - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - if m.Rx1Delay == nil { - m.Rx1Delay = &MACSettings_RxDelayValue{} + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MACSettings_DataRateIndexValue) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice } - if err := m.Rx1Delay.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + if iNdEx >= l { + return io.ErrUnexpectedEOF } - iNdEx = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rx2DataRateIndex", wireType) + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break } - var msglen int + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DataRateIndexValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DataRateIndexValue: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + m.Value = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEndDevice @@ -7766,30 +8770,66 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= (int(b) & 0x7F) << shift + m.Value |= (DataRateIndex(b) & 0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + default: + iNdEx = preIndex + skippy, err := skipEndDevice(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { return ErrInvalidLengthEndDevice } - postIndex := iNdEx + msglen - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - if m.Rx2DataRateIndex == nil { - m.Rx2DataRateIndex = &MACSettings_DataRateIndexValue{} + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MACSettings_PingSlotPeriodValue) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEndDevice } - if err := m.Rx2DataRateIndex.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + if iNdEx >= l { + return io.ErrUnexpectedEOF } - iNdEx = postIndex - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rx2Frequency", wireType) + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break } - var msglen int + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PingSlotPeriodValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PingSlotPeriodValue: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + m.Value = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEndDevice @@ -7799,25 +8839,11 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= (int(b) & 0x7F) << shift + m.Value |= (PingSlotPeriod(b) & 0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthEndDevice - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Rx2Frequency == nil { - m.Rx2Frequency = &types.UInt64Value{} - } - if err := m.Rx2Frequency.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEndDevice(dAtA[iNdEx:]) @@ -7839,7 +8865,7 @@ func (m *MACSettings) Unmarshal(dAtA []byte) error { } return nil } -func (m *MACSettings_RxDelayValue) Unmarshal(dAtA []byte) error { +func (m *MACSettings_AggregatedDutyCycleValue) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -7862,10 +8888,10 @@ func (m *MACSettings_RxDelayValue) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RxDelayValue: wiretype end group for non-group") + return fmt.Errorf("proto: AggregatedDutyCycleValue: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RxDelayValue: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AggregatedDutyCycleValue: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -7882,7 +8908,7 @@ func (m *MACSettings_RxDelayValue) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Value |= (RxDelay(b) & 0x7F) << shift + m.Value |= (AggregatedDutyCycle(b) & 0x7F) << shift if b < 0x80 { break } @@ -7908,7 +8934,7 @@ func (m *MACSettings_RxDelayValue) Unmarshal(dAtA []byte) error { } return nil } -func (m *MACSettings_DataRateIndexValue) Unmarshal(dAtA []byte) error { +func (m *MACSettings_RxDelayValue) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -7931,10 +8957,10 @@ func (m *MACSettings_DataRateIndexValue) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DataRateIndexValue: wiretype end group for non-group") + return fmt.Errorf("proto: RxDelayValue: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DataRateIndexValue: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RxDelayValue: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -7951,7 +8977,7 @@ func (m *MACSettings_DataRateIndexValue) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Value |= (DataRateIndex(b) & 0x7F) << shift + m.Value |= (RxDelay(b) & 0x7F) << shift if b < 0x80 { break } @@ -9193,39 +10219,6 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { m.FrequencyPlanID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 18: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DefaultMACParameters", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEndDevice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEndDevice - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.DefaultMACParameters == nil { - m.DefaultMACParameters = &MACParameters{} - } - if err := m.DefaultMACParameters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 19: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field MinFrequency", wireType) } @@ -9244,7 +10237,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { break } } - case 20: + case 19: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field MaxFrequency", wireType) } @@ -9263,47 +10256,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { break } } - case 21: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ResetsFCnt", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEndDevice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.ResetsFCnt = bool(v != 0) - case 22: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Uses32BitFCnt", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEndDevice - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.Uses32BitFCnt = bool(v != 0) - case 23: + case 20: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SupportsJoin", wireType) } @@ -9323,7 +10276,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { } } m.SupportsJoin = bool(v != 0) - case 24: + case 21: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field ResetsJoinNonces", wireType) } @@ -9343,7 +10296,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { } } m.ResetsJoinNonces = bool(v != 0) - case 25: + case 22: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field RootKeys", wireType) } @@ -9376,7 +10329,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 26: + case 23: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field NetID", wireType) } @@ -9408,7 +10361,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 27: + case 24: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field MACSettings", wireType) } @@ -9441,7 +10394,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 28: + case 25: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field MACState", wireType) } @@ -9474,7 +10427,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 29: + case 26: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Session", wireType) } @@ -9507,7 +10460,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 30: + case 27: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field PendingSession", wireType) } @@ -9540,7 +10493,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 31: + case 28: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field LastDevNonce", wireType) } @@ -9559,7 +10512,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { break } } - case 32: + case 29: if wireType == 0 { var v uint32 for shift := uint(0); ; shift += 7 { @@ -9632,7 +10585,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { } else { return fmt.Errorf("proto: wrong wireType = %d for field UsedDevNonces", wireType) } - case 33: + case 30: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field LastJoinNonce", wireType) } @@ -9651,7 +10604,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { break } } - case 34: + case 31: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field LastRJCount0", wireType) } @@ -9670,7 +10623,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { break } } - case 35: + case 32: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field LastRJCount1", wireType) } @@ -9689,7 +10642,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { break } } - case 36: + case 33: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field LastDevStatusReceivedAt", wireType) } @@ -9722,7 +10675,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 37: + case 34: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field PowerState", wireType) } @@ -9741,7 +10694,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { break } } - case 38: + case 35: if wireType != 5 { return fmt.Errorf("proto: wrong wireType = %d for field BatteryPercentage", wireType) } @@ -9752,7 +10705,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { v = encoding_binary.LittleEndian.Uint32(dAtA[iNdEx:]) iNdEx += 4 m.BatteryPercentage = float32(math.Float32frombits(v)) - case 39: + case 36: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field DownlinkMargin", wireType) } @@ -9771,7 +10724,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { break } } - case 40: + case 37: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field RecentADRUplinks", wireType) } @@ -9802,7 +10755,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 41: + case 38: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field RecentUplinks", wireType) } @@ -9833,7 +10786,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 42: + case 39: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field RecentDownlinks", wireType) } @@ -9864,7 +10817,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 43: + case 40: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field QueuedApplicationDownlinks", wireType) } @@ -9895,7 +10848,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 44: + case 41: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Formatters", wireType) } @@ -9928,7 +10881,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 45: + case 42: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProvisionerID", wireType) } @@ -9957,7 +10910,7 @@ func (m *EndDevice) Unmarshal(dAtA []byte) error { } m.ProvisionerID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 46: + case 43: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProvisioningData", wireType) } @@ -10785,234 +11738,246 @@ var ( ) func init() { - proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_f29faf389d9d861a) + proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_7df2e0db88789f5d) } func init() { - golang_proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_f29faf389d9d861a) -} - -var fileDescriptor_end_device_f29faf389d9d861a = []byte{ - // 3549 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5a, 0x4b, 0x6c, 0x23, 0xc7, - 0x99, 0x66, 0x53, 0x1a, 0x89, 0x2c, 0x52, 0x7c, 0x94, 0x34, 0x33, 0x6d, 0x79, 0x4c, 0xca, 0x9a, - 0xb1, 0x43, 0x3b, 0x16, 0x35, 0xa3, 0x19, 0xe7, 0x31, 0x49, 0x30, 0x26, 0x45, 0x8d, 0x2d, 0x47, - 0xa3, 0xd1, 0xd6, 0xbc, 0xd6, 0x49, 0xc6, 0x8d, 0x12, 0xbb, 0x44, 0xb5, 0x45, 0x76, 0x77, 0xaa, - 0x8a, 0x12, 0xb5, 0x0f, 0x20, 0x97, 0x05, 0x72, 0x4b, 0x0e, 0xbb, 0x40, 0x2e, 0x0b, 0x04, 0x8b, - 0x5d, 0x20, 0x58, 0xec, 0x21, 0x47, 0x1f, 0x73, 0xf4, 0x6d, 0x7d, 0x0c, 0x72, 0xe0, 0x64, 0xa8, - 0x4b, 0x8e, 0x01, 0xf6, 0xe2, 0xe3, 0xa2, 0x1e, 0xfd, 0xe0, 0x43, 0xb2, 0x64, 0xaf, 0xf7, 0x22, - 0x74, 0xff, 0xff, 0xf7, 0x7f, 0xfd, 0xd7, 0xeb, 0x7f, 0x14, 0x05, 0x96, 0xdb, 0x1e, 0xc5, 0x47, - 0xd8, 0x5d, 0x61, 0x1c, 0x37, 0x0f, 0x56, 0xb1, 0xef, 0xac, 0x12, 0xd7, 0xb6, 0x6c, 0x72, 0xe8, - 0x34, 0x49, 0xd5, 0xa7, 0x1e, 0xf7, 0x60, 0x8e, 0x73, 0xb7, 0xaa, 0x71, 0xd5, 0xc3, 0xdb, 0x8b, - 0x2b, 0x2d, 0x87, 0xef, 0x77, 0x77, 0xab, 0x4d, 0xaf, 0xb3, 0xda, 0xf2, 0x5a, 0xde, 0xaa, 0x84, - 0xed, 0x76, 0xf7, 0xe4, 0x9b, 0x7c, 0x91, 0x4f, 0xca, 0x7c, 0xf1, 0x3b, 0x31, 0x78, 0xe7, 0xc8, - 0xe1, 0x07, 0xde, 0xd1, 0x6a, 0xcb, 0x5b, 0x91, 0xca, 0x95, 0x43, 0xdc, 0x76, 0x6c, 0xcc, 0x3d, - 0xca, 0x56, 0xc3, 0x47, 0x6d, 0x77, 0xad, 0xe5, 0x79, 0xad, 0x36, 0x91, 0x3e, 0x61, 0xd7, 0xf5, - 0x38, 0xe6, 0x8e, 0xe7, 0x32, 0xad, 0x2d, 0x69, 0x6d, 0xf8, 0x6d, 0xbb, 0x4b, 0x25, 0x40, 0xeb, - 0x97, 0x46, 0xf5, 0x7b, 0x0e, 0x69, 0xdb, 0x56, 0x07, 0xb3, 0x83, 0x11, 0xfe, 0x10, 0xc1, 0x38, - 0xed, 0x36, 0xb9, 0xd6, 0x96, 0x47, 0xb5, 0xdc, 0xe9, 0x10, 0xc6, 0x71, 0xc7, 0x3f, 0xcd, 0x81, - 0x23, 0x8a, 0x7d, 0x9f, 0xd0, 0xc0, 0xc1, 0xeb, 0xe3, 0x33, 0xeb, 0xd8, 0xc4, 0xe5, 0xce, 0x9e, - 0x13, 0x81, 0xae, 0x8d, 0x83, 0x3e, 0xf1, 0x1c, 0xf7, 0x74, 0xed, 0x01, 0x39, 0x0e, 0x6c, 0xcb, - 0xe3, 0xda, 0x60, 0x91, 0xf4, 0x14, 0x8c, 0x03, 0x3a, 0x84, 0x31, 0xdc, 0x22, 0xec, 0x2c, 0x04, - 0xc7, 0x36, 0xe6, 0x58, 0x21, 0x96, 0x7f, 0x35, 0x05, 0x66, 0x1f, 0x11, 0xc6, 0x1c, 0xcf, 0x85, - 0xcf, 0x40, 0xca, 0x26, 0x87, 0x16, 0xb6, 0x6d, 0x6a, 0x26, 0x97, 0x8c, 0x4a, 0xb6, 0xfe, 0xc3, - 0xcf, 0xfa, 0xe5, 0xc4, 0x9f, 0xfa, 0xe5, 0x3b, 0x2d, 0xaf, 0xca, 0xf7, 0x09, 0xdf, 0x77, 0xdc, - 0x16, 0xab, 0xba, 0x84, 0x1f, 0x79, 0xf4, 0x60, 0x75, 0x98, 0xdc, 0x3f, 0x68, 0xad, 0xf2, 0x63, - 0x9f, 0xb0, 0x6a, 0x83, 0x1c, 0xd6, 0x6c, 0x9b, 0xa2, 0x59, 0x5b, 0x3d, 0xc0, 0xef, 0x83, 0x69, - 0x31, 0x2e, 0x73, 0x6a, 0xc9, 0xa8, 0x64, 0xd6, 0x5e, 0xad, 0x0e, 0xef, 0xb7, 0xaa, 0xfe, 0xfe, - 0x8f, 0xc9, 0x31, 0xab, 0xa7, 0xc4, 0x17, 0x3f, 0xef, 0x97, 0x0d, 0x24, 0x4d, 0xe0, 0xeb, 0x60, - 0xae, 0x8d, 0x19, 0xb7, 0xf6, 0xac, 0xa6, 0xcb, 0xad, 0xae, 0x6f, 0x4e, 0x2f, 0x19, 0x95, 0x39, - 0x04, 0x84, 0xf0, 0xfe, 0xba, 0xcb, 0x9f, 0xf8, 0xb0, 0x02, 0x8a, 0x12, 0xe2, 0x6a, 0x90, 0xed, - 0x1d, 0xb9, 0xe6, 0x25, 0x09, 0x93, 0xb6, 0xdb, 0x02, 0xd7, 0xf0, 0x8e, 0xdc, 0x10, 0x89, 0xe3, - 0xc8, 0x99, 0x08, 0x59, 0x0b, 0x91, 0x55, 0xb0, 0x20, 0x91, 0x4d, 0xcf, 0xdd, 0x8b, 0x83, 0x67, - 0x25, 0xb8, 0x20, 0x74, 0xeb, 0x9e, 0xbb, 0x17, 0xe2, 0xd7, 0x01, 0x60, 0x1c, 0x53, 0x4e, 0x6c, - 0x0b, 0x73, 0x33, 0x25, 0xc7, 0xb9, 0x58, 0x55, 0x3b, 0xa8, 0x1a, 0xec, 0xa0, 0xea, 0xe3, 0x60, - 0x8b, 0xa9, 0x61, 0xfe, 0xfa, 0x45, 0xd9, 0x40, 0x69, 0x6d, 0x57, 0xe3, 0x1f, 0x4e, 0xa7, 0x8c, - 0x42, 0x72, 0xf9, 0x45, 0x06, 0xcc, 0x3d, 0xa8, 0xad, 0xef, 0x60, 0x8a, 0x3b, 0x84, 0x13, 0xca, - 0xe0, 0x9b, 0x20, 0xd5, 0xc1, 0x3d, 0x8b, 0x38, 0xd4, 0x37, 0x8d, 0x25, 0xa3, 0x92, 0xac, 0x67, - 0x06, 0xfd, 0xf2, 0xec, 0x03, 0xdc, 0xdb, 0xd8, 0x44, 0x3b, 0x68, 0xb6, 0x83, 0x7b, 0x1b, 0x0e, - 0xf5, 0xe1, 0xdb, 0xa0, 0xd8, 0xf5, 0xdb, 0x8e, 0x7b, 0x60, 0xd9, 0x47, 0xa4, 0xdd, 0xb6, 0xc4, - 0x8e, 0x96, 0x0b, 0x99, 0x42, 0x79, 0xa5, 0x68, 0x08, 0xb9, 0xf0, 0x02, 0x56, 0xc1, 0xbc, 0x18, - 0xd0, 0x28, 0x7a, 0x4a, 0xa2, 0x8b, 0x81, 0x2a, 0xc2, 0xef, 0x82, 0x79, 0x6c, 0x53, 0x4b, 0xec, - 0x1c, 0x8b, 0x62, 0x4e, 0x2c, 0xc7, 0xb5, 0x49, 0x4f, 0xae, 0x46, 0x6e, 0xed, 0xb5, 0xd1, 0x15, - 0x6d, 0x60, 0x8e, 0x11, 0xe6, 0x64, 0x53, 0x80, 0xea, 0x0b, 0x83, 0x7e, 0xb9, 0x50, 0x6b, 0xa0, - 0x21, 0x29, 0x2a, 0x60, 0x9b, 0x0e, 0x49, 0xe0, 0x7b, 0x00, 0x8a, 0x6f, 0xf0, 0x9e, 0xe5, 0x7b, - 0x47, 0x84, 0xea, 0x4f, 0xc8, 0x95, 0xac, 0xcf, 0x0f, 0xfa, 0xe5, 0x7c, 0xad, 0x81, 0x1e, 0xf7, - 0x76, 0x84, 0x4e, 0x51, 0xe4, 0xb1, 0x4d, 0xe3, 0x02, 0x78, 0x13, 0x64, 0x05, 0x83, 0xbb, 0x6b, - 0x71, 0x8a, 0x5d, 0xa6, 0xd6, 0xb6, 0x9e, 0x1b, 0xf4, 0xcb, 0xa0, 0xd6, 0x40, 0xdb, 0xbb, 0x8f, - 0x85, 0x14, 0x01, 0x6c, 0x53, 0xfd, 0x0c, 0x6f, 0x83, 0x39, 0x61, 0x81, 0x9b, 0x07, 0x56, 0xdb, - 0xe9, 0x38, 0x5c, 0xad, 0x70, 0x3d, 0x3f, 0xe8, 0x97, 0x33, 0xb5, 0x06, 0xaa, 0x35, 0x0f, 0xb6, - 0x84, 0x18, 0x65, 0xb0, 0x4d, 0x83, 0x97, 0xb8, 0x91, 0x4d, 0xda, 0xf8, 0x58, 0x2e, 0xf8, 0x90, - 0x51, 0x43, 0x88, 0x03, 0x23, 0xf9, 0x02, 0xef, 0x80, 0x34, 0xed, 0xdd, 0xd2, 0x06, 0x69, 0x39, - 0x6f, 0x57, 0x47, 0xe7, 0x0d, 0xf5, 0x94, 0x61, 0x8a, 0xf6, 0x6e, 0x29, 0xab, 0x55, 0xb0, 0x20, - 0xad, 0xc2, 0x79, 0xf7, 0xf6, 0xf6, 0x18, 0xe1, 0x26, 0x90, 0x1b, 0xb1, 0x28, 0x70, 0x7a, 0x0e, - 0x1f, 0x4a, 0x05, 0xdc, 0x02, 0xf3, 0xb4, 0xb7, 0x36, 0xb6, 0x50, 0x99, 0x73, 0x2c, 0x14, 0x2a, - 0xd0, 0xde, 0xda, 0xf0, 0x92, 0x5c, 0x07, 0x73, 0x82, 0x6d, 0x8f, 0x92, 0x9f, 0x77, 0x89, 0xdb, - 0x3c, 0x36, 0xb3, 0x4b, 0x46, 0x65, 0x1a, 0x65, 0x69, 0x6f, 0xed, 0x7e, 0x20, 0x83, 0x3f, 0x01, - 0x57, 0x29, 0x11, 0x61, 0x4d, 0xee, 0x21, 0xcb, 0x27, 0xd4, 0xf1, 0x6c, 0xa7, 0xe9, 0xf0, 0x63, - 0x73, 0x4e, 0x7e, 0x76, 0x79, 0x6c, 0x9c, 0x12, 0x2e, 0x36, 0xd6, 0x46, 0xcf, 0xf7, 0x5c, 0xe2, - 0x72, 0x74, 0x99, 0x86, 0xb2, 0x9d, 0x88, 0x00, 0x3e, 0x07, 0xa6, 0xe6, 0x6e, 0x7a, 0x5d, 0x97, - 0x0f, 0x91, 0xe7, 0x24, 0xf9, 0xf5, 0xc9, 0xe4, 0xeb, 0x02, 0x1e, 0xb2, 0x5f, 0xa1, 0x91, 0x30, - 0x4e, 0xbf, 0x09, 0x72, 0xe2, 0x68, 0xd9, 0x5d, 0x7e, 0x6c, 0x35, 0x8f, 0x9b, 0x6d, 0x62, 0xe6, - 0x27, 0x93, 0xd6, 0x5a, 0x2d, 0x4a, 0x5a, 0x98, 0x13, 0xbb, 0xd1, 0xe5, 0xc7, 0xeb, 0x02, 0x8a, - 0xb2, 0x1d, 0xdc, 0x0b, 0xdf, 0x60, 0x0d, 0xa4, 0x9a, 0xfb, 0xd8, 0x75, 0x49, 0x9b, 0x99, 0x85, - 0xa5, 0xa9, 0x4a, 0x66, 0xed, 0x8d, 0x51, 0x92, 0xa1, 0x63, 0x5d, 0x5d, 0x57, 0x68, 0x14, 0x9a, - 0x89, 0x43, 0xe9, 0x3b, 0x6e, 0xcb, 0x62, 0x6d, 0x8f, 0xc7, 0xe6, 0xbc, 0x28, 0xe7, 0xbc, 0x28, - 0x54, 0x8f, 0xda, 0x1e, 0x8f, 0x26, 0xfe, 0x19, 0x78, 0x25, 0xc2, 0x8f, 0xae, 0x38, 0x3c, 0xcf, - 0x8a, 0x5f, 0x0e, 0x48, 0x87, 0x97, 0xfd, 0x2d, 0x50, 0xd8, 0x25, 0xb8, 0xe9, 0xb9, 0x31, 0x2f, - 0xe6, 0xa5, 0x17, 0x79, 0x25, 0x0f, 0x7d, 0x58, 0xfc, 0xcf, 0x24, 0x98, 0xd5, 0x23, 0x11, 0x66, - 0x3a, 0x00, 0x45, 0x66, 0x86, 0x32, 0x53, 0xf2, 0xc8, 0xf5, 0x15, 0x00, 0xc3, 0xf8, 0x13, 0x81, - 0x93, 0x6a, 0xa4, 0x81, 0x26, 0x82, 0x6f, 0x81, 0xf9, 0x8e, 0xe3, 0x8e, 0x8d, 0x71, 0xea, 0x5c, - 0xbb, 0xba, 0xe3, 0xb8, 0xc3, 0xc3, 0x13, 0x6c, 0x62, 0xd5, 0xbf, 0x42, 0x30, 0x43, 0x05, 0xb1, - 0xe8, 0xa3, 0x67, 0x84, 0xb8, 0x78, 0xb7, 0x4d, 0x2c, 0x35, 0x48, 0x19, 0xb1, 0x52, 0x28, 0xab, - 0x84, 0x4f, 0xa4, 0xec, 0xee, 0xf4, 0xa7, 0xbf, 0x2d, 0x27, 0xd4, 0xdf, 0xe5, 0x0e, 0xc8, 0x6d, - 0xb8, 0x76, 0x43, 0x96, 0x60, 0x75, 0x8a, 0x5d, 0x1b, 0x5e, 0x01, 0x49, 0xc7, 0x96, 0x53, 0x95, - 0xae, 0xcf, 0x0c, 0xfa, 0xe5, 0xe4, 0x66, 0x03, 0x25, 0x1d, 0x1b, 0x42, 0x30, 0xed, 0x62, 0x1d, - 0xc4, 0xd3, 0x48, 0x3e, 0xc3, 0x57, 0xc0, 0x54, 0x97, 0xb6, 0xe5, 0xd0, 0xd3, 0xf5, 0xd9, 0x41, - 0xbf, 0x3c, 0xf5, 0x04, 0x6d, 0x21, 0x21, 0x83, 0x0b, 0xe0, 0x52, 0xdb, 0x6b, 0x79, 0xcc, 0x9c, - 0x5e, 0x9a, 0xaa, 0xa4, 0x91, 0x7a, 0x59, 0xb6, 0x63, 0x9f, 0x7b, 0xe0, 0xd9, 0xa4, 0x2d, 0x12, - 0xca, 0xae, 0xf8, 0xae, 0x15, 0x7e, 0x54, 0x26, 0x14, 0xe9, 0xcb, 0x66, 0x03, 0xcd, 0x4a, 0xe5, - 0x66, 0xe0, 0x56, 0xf2, 0x54, 0xb7, 0xa6, 0x22, 0xb7, 0x96, 0xff, 0x25, 0x09, 0x5e, 0x0d, 0x3f, - 0xf3, 0x94, 0x50, 0x91, 0xd1, 0x37, 0xa3, 0x7a, 0x08, 0x3e, 0x1c, 0xfb, 0xe6, 0x9d, 0xd8, 0x37, - 0x07, 0x2f, 0xca, 0x6f, 0x80, 0xd7, 0x3f, 0xfe, 0x29, 0x5e, 0xf9, 0xbb, 0x9b, 0x2b, 0xdf, 0x7f, - 0x5e, 0xb9, 0x77, 0xf7, 0xa7, 0x2b, 0xcf, 0xef, 0x05, 0xaf, 0x6f, 0xfd, 0xfd, 0xda, 0x3b, 0xff, - 0x78, 0xe3, 0x1f, 0x3e, 0xbe, 0xd1, 0x7b, 0x23, 0x72, 0xee, 0x21, 0x48, 0x75, 0xc4, 0x68, 0xac, - 0xd0, 0x45, 0x49, 0x28, 0x47, 0x78, 0x21, 0x42, 0xc9, 0xb2, 0x69, 0x8b, 0xdd, 0xbb, 0x8f, 0xa9, - 0x7d, 0x84, 0x29, 0xb1, 0x0e, 0xd5, 0x00, 0xf4, 0x08, 0xf3, 0x81, 0x5c, 0x8f, 0x4b, 0x40, 0xf7, - 0x1c, 0xda, 0x19, 0x82, 0x4e, 0x2b, 0x68, 0x20, 0xd7, 0xd0, 0xe5, 0x7f, 0x9e, 0x05, 0x85, 0xd1, - 0x79, 0x81, 0xef, 0x83, 0x29, 0xc7, 0x66, 0x72, 0x1e, 0x32, 0x6b, 0xdf, 0x1e, 0xdd, 0x70, 0x67, - 0x4c, 0x63, 0xac, 0x3e, 0x12, 0x0c, 0xf0, 0x19, 0xc8, 0x6b, 0xc3, 0xd0, 0x8f, 0xa4, 0xdc, 0xc5, - 0x8b, 0x13, 0x62, 0x8f, 0xa6, 0xab, 0xc3, 0x41, 0xbf, 0x9c, 0xdb, 0xf2, 0x10, 0x7e, 0x56, 0xdb, - 0xd6, 0x32, 0x94, 0xd3, 0xd0, 0xc0, 0x43, 0x0c, 0xe6, 0x03, 0x62, 0x7f, 0xff, 0x78, 0x68, 0x3e, - 0x26, 0x90, 0xef, 0x7c, 0xf0, 0x51, 0x40, 0x7e, 0x79, 0xd0, 0x2f, 0x17, 0x35, 0x79, 0x24, 0x46, - 0x45, 0x8d, 0xde, 0xd9, 0x3f, 0x0e, 0x3e, 0x71, 0x0f, 0x14, 0xc3, 0x93, 0x6f, 0xf9, 0x6d, 0xec, - 0x8a, 0x95, 0x94, 0xb3, 0xa8, 0xb2, 0x7d, 0x78, 0xfa, 0x77, 0xda, 0xd8, 0xdd, 0x6c, 0xa0, 0xfc, - 0xde, 0x90, 0x40, 0x6c, 0xcf, 0x19, 0x7f, 0xdf, 0xe3, 0x1e, 0x33, 0x2f, 0xc9, 0xfd, 0xae, 0xdf, - 0x60, 0x05, 0x14, 0x58, 0xd7, 0xf7, 0x3d, 0xca, 0x99, 0xd5, 0x6c, 0x63, 0xc6, 0xac, 0x5d, 0x59, - 0x09, 0xa4, 0x50, 0x2e, 0x90, 0xaf, 0x0b, 0x71, 0x7d, 0x02, 0xb2, 0x29, 0x0b, 0x80, 0x51, 0xe4, - 0x3a, 0xec, 0x80, 0x2b, 0x36, 0xd9, 0xc3, 0xdd, 0x36, 0xb7, 0x3a, 0xb8, 0x69, 0xf9, 0x61, 0x18, - 0xd7, 0xc5, 0xde, 0x6b, 0x67, 0xc6, 0xfa, 0xba, 0x39, 0xe8, 0x97, 0x17, 0x1a, 0x8a, 0x60, 0x48, - 0x83, 0x16, 0x34, 0xed, 0x03, 0xdc, 0x8c, 0x95, 0x7c, 0xd7, 0xc1, 0x9c, 0x88, 0x77, 0x51, 0x64, - 0x4c, 0xab, 0xbc, 0xdb, 0x71, 0xa2, 0xd0, 0x2b, 0x41, 0xb8, 0x17, 0x03, 0x01, 0x0d, 0xc2, 0xbd, - 0x08, 0xb4, 0x04, 0xb2, 0x94, 0x30, 0xc2, 0x99, 0x2a, 0x63, 0x65, 0x21, 0x90, 0x42, 0x40, 0xc9, - 0x44, 0xfd, 0x0a, 0x7f, 0x00, 0x8a, 0x5d, 0x46, 0x98, 0x75, 0x7b, 0xcd, 0xda, 0x75, 0x74, 0xa5, - 0x2d, 0xf3, 0x7c, 0xaa, 0x5e, 0x1c, 0xf4, 0xcb, 0x73, 0x4f, 0x18, 0x61, 0xb7, 0xd7, 0xea, 0x8e, - 0xac, 0xb7, 0xd1, 0x5c, 0x37, 0xfe, 0x2a, 0x7c, 0x08, 0x67, 0x50, 0x64, 0x58, 0x99, 0xf1, 0x53, - 0x28, 0x1b, 0x08, 0x3f, 0xf4, 0x1c, 0x17, 0xbe, 0x03, 0xa0, 0xf6, 0x41, 0x66, 0x72, 0xd7, 0x73, - 0x9b, 0x84, 0xc9, 0xf4, 0x9d, 0x42, 0x05, 0xa5, 0x11, 0xb8, 0x6d, 0x29, 0x87, 0xcf, 0x01, 0x0c, - 0xa6, 0x7a, 0xcf, 0xa3, 0x1d, 0xcc, 0xe5, 0x34, 0xe7, 0xe5, 0x34, 0x57, 0xc6, 0xa6, 0x59, 0x35, - 0x3c, 0x3b, 0xf8, 0xb8, 0xed, 0x61, 0xfb, 0x7e, 0x88, 0xaf, 0x4f, 0x8b, 0x83, 0x82, 0x8a, 0x9a, - 0x29, 0x52, 0xe8, 0x18, 0xfc, 0xdf, 0x33, 0x20, 0xf3, 0xa0, 0xb6, 0xfe, 0x88, 0x70, 0x2e, 0x7a, - 0x1a, 0x78, 0x0f, 0xcc, 0x76, 0x19, 0xb1, 0xb0, 0x4d, 0xf5, 0xa9, 0x1c, 0xaf, 0xde, 0xeb, 0x9e, - 0xd7, 0x7e, 0x8a, 0xdb, 0x5d, 0x52, 0x07, 0x83, 0x7e, 0x79, 0xe6, 0x09, 0x23, 0xb5, 0x06, 0x42, - 0x33, 0x5d, 0x46, 0x6a, 0x36, 0x85, 0x9b, 0x40, 0x94, 0x95, 0x56, 0x07, 0xd3, 0x96, 0xa3, 0x0e, - 0xa1, 0xe8, 0x74, 0x46, 0x39, 0xee, 0xb7, 0x3d, 0xcc, 0x15, 0xc9, 0xdc, 0xa0, 0x5f, 0x4e, 0xd7, - 0x1a, 0xe8, 0x81, 0xb4, 0x40, 0x69, 0x6c, 0x53, 0xf5, 0x08, 0xdf, 0x07, 0x79, 0xbd, 0x6d, 0x65, - 0x41, 0xe5, 0x75, 0xb9, 0xee, 0x9c, 0x5e, 0x19, 0xe3, 0x6b, 0xe8, 0xa6, 0xb8, 0x3e, 0xfd, 0x1b, - 0xd1, 0x4c, 0xcc, 0x49, 0xbb, 0xfa, 0x63, 0x65, 0x15, 0x11, 0x35, 0x43, 0xa2, 0xe9, 0x8b, 0x10, - 0xad, 0x07, 0x44, 0xcf, 0xc0, 0x55, 0xc6, 0x31, 0xef, 0xb2, 0xf1, 0x0a, 0xef, 0xd2, 0xf9, 0x08, - 0x2f, 0x2b, 0xfb, 0xd1, 0xf2, 0xee, 0x29, 0x30, 0x35, 0xf1, 0x78, 0x79, 0x37, 0x23, 0x99, 0xaf, - 0x8d, 0x31, 0x3f, 0xd9, 0x74, 0xf9, 0xed, 0x35, 0x39, 0x89, 0xe8, 0x8a, 0xb2, 0x1e, 0xab, 0xeb, - 0x36, 0xe2, 0xc5, 0xf6, 0xec, 0x29, 0x5b, 0x27, 0x5a, 0xfe, 0xa0, 0xf0, 0x56, 0xa4, 0x51, 0xf5, - 0xfd, 0x7c, 0x72, 0x31, 0xad, 0x8e, 0x7c, 0xf5, 0x2c, 0xc2, 0xa1, 0x12, 0x41, 0xd1, 0x8e, 0x57, - 0xd7, 0xb5, 0xd1, 0xea, 0x3a, 0x7d, 0xc6, 0x90, 0xbf, 0x73, 0x47, 0xd1, 0x0c, 0xd5, 0xde, 0x8b, - 0x3f, 0x02, 0xd9, 0xb8, 0xef, 0x70, 0x05, 0x5c, 0x3a, 0x14, 0x0f, 0x72, 0x17, 0x9f, 0xd1, 0x61, - 0x28, 0xd4, 0xe2, 0x26, 0x80, 0xe3, 0x9e, 0xc2, 0xdb, 0xc3, 0x24, 0x5f, 0x52, 0x11, 0x29, 0xec, - 0xf2, 0x7f, 0xa4, 0x41, 0x4a, 0xcc, 0x00, 0xc7, 0x9c, 0x40, 0x04, 0x60, 0xb3, 0x4b, 0x29, 0x11, - 0x4b, 0x1a, 0x85, 0x4a, 0xe3, 0x3c, 0xa1, 0x52, 0x1f, 0x5c, 0x6d, 0x1e, 0x8b, 0x89, 0x48, 0xc4, - 0x05, 0xe6, 0x50, 0x62, 0xc7, 0x39, 0x93, 0x17, 0xe0, 0xd4, 0xe6, 0x31, 0xce, 0xef, 0x81, 0xac, - 0xba, 0x0a, 0x53, 0xe1, 0x5f, 0xe7, 0xb7, 0xcb, 0xa3, 0x6c, 0x32, 0x09, 0xa0, 0x8c, 0x82, 0xca, - 0x97, 0x49, 0x99, 0x77, 0xfa, 0xff, 0x24, 0xf3, 0x3e, 0x07, 0x8b, 0xe1, 0xd5, 0x83, 0x43, 0x3b, - 0xc4, 0xb6, 0xc2, 0x42, 0x19, 0x73, 0x7d, 0xdc, 0xce, 0xba, 0x5a, 0x98, 0x96, 0xd7, 0x0a, 0x57, - 0x83, 0x2b, 0x0a, 0x49, 0xd1, 0xd0, 0x0c, 0x35, 0x0e, 0xdf, 0x05, 0xa6, 0xa4, 0xb7, 0xc9, 0xa1, - 0xa5, 0x8f, 0x5e, 0x78, 0xb7, 0xa2, 0xae, 0x42, 0xe6, 0x85, 0xbe, 0x41, 0x0e, 0x1f, 0x49, 0xad, - 0xbe, 0x64, 0x41, 0xe0, 0x72, 0xd4, 0x6a, 0xc4, 0x4f, 0xe9, 0xac, 0x1c, 0x74, 0x69, 0xac, 0x22, - 0xd0, 0x7d, 0x85, 0x3a, 0x94, 0x68, 0xde, 0x1f, 0x7a, 0x57, 0x87, 0x94, 0x80, 0x6b, 0x3e, 0x71, - 0x6d, 0x41, 0x8b, 0x7d, 0xbf, 0xed, 0x34, 0x65, 0xc0, 0x08, 0x87, 0xab, 0x8f, 0xd9, 0x78, 0x2b, - 0x16, 0x61, 0x83, 0x71, 0xa1, 0x45, 0x4d, 0x34, 0x41, 0x07, 0x37, 0x40, 0xe1, 0xe7, 0x5d, 0xd2, - 0x25, 0xb6, 0x45, 0x09, 0xf3, 0x3d, 0x97, 0x11, 0x66, 0xa6, 0x65, 0x83, 0x36, 0x69, 0xa9, 0xd6, - 0xbd, 0x4e, 0x07, 0xbb, 0x36, 0xca, 0x2b, 0x1b, 0x14, 0x98, 0x08, 0x9a, 0xc0, 0x5b, 0x79, 0xfa, - 0x18, 0x67, 0x26, 0xf8, 0x72, 0x1a, 0x6d, 0x83, 0xb4, 0x09, 0xfc, 0x1b, 0x00, 0xb5, 0x37, 0x32, - 0x17, 0xe2, 0x66, 0x93, 0xf8, 0x2a, 0x2b, 0x4f, 0x18, 0x6a, 0x70, 0x9e, 0xaa, 0x22, 0x3d, 0xd6, - 0x24, 0x14, 0xe9, 0xc1, 0x44, 0x12, 0xf8, 0x00, 0x2c, 0x04, 0x9e, 0x49, 0x4e, 0xed, 0x9e, 0xcc, - 0xe1, 0x13, 0xae, 0xdb, 0x84, 0xa5, 0x76, 0x07, 0x41, 0x6d, 0x18, 0x93, 0xc1, 0x9b, 0x60, 0x81, - 0xf6, 0xac, 0x23, 0xc7, 0xb5, 0xbd, 0x23, 0x66, 0xe1, 0x43, 0xec, 0xb4, 0x45, 0x23, 0xa3, 0x33, - 0x3b, 0xa4, 0xbd, 0x67, 0x4a, 0x55, 0x0b, 0x34, 0x8b, 0xff, 0x6e, 0x00, 0x10, 0xf3, 0x67, 0x19, - 0xcc, 0xfa, 0x2a, 0x1f, 0xcb, 0x13, 0x9f, 0xad, 0xa7, 0x06, 0x2f, 0xca, 0xd3, 0x7e, 0xa6, 0xf7, - 0x1a, 0x0a, 0x14, 0xf0, 0x07, 0x60, 0x36, 0x70, 0x33, 0xf9, 0xa5, 0x6e, 0xea, 0xf3, 0x1b, 0x58, - 0xc0, 0x77, 0xcf, 0x7f, 0x9f, 0xa8, 0x2c, 0x25, 0x5c, 0x67, 0xfe, 0x7f, 0x32, 0x41, 0x3a, 0xac, - 0xb0, 0xe1, 0x7b, 0xf1, 0x4a, 0xfc, 0xc6, 0xa9, 0x95, 0xf8, 0x19, 0x25, 0xf8, 0x3a, 0x00, 0x4d, - 0x4a, 0xb0, 0xbe, 0xfa, 0x4b, 0x5e, 0xe4, 0xea, 0x4f, 0xdb, 0xd5, 0xb8, 0x20, 0xe9, 0xfa, 0x76, - 0x40, 0x32, 0x75, 0x11, 0x12, 0x6d, 0x57, 0xe3, 0x61, 0x5b, 0x36, 0x1d, 0xeb, 0x16, 0x97, 0x40, - 0xc6, 0x26, 0xac, 0x49, 0x1d, 0x5f, 0x9c, 0x09, 0x19, 0x3e, 0xd2, 0x28, 0x2e, 0x92, 0x85, 0x0b, - 0xe7, 0xd4, 0xd9, 0xed, 0x72, 0xc2, 0xcc, 0x19, 0xb9, 0xa3, 0xdf, 0x3a, 0x75, 0x22, 0xaa, 0xb5, - 0x10, 0xbb, 0xe1, 0x72, 0x7a, 0x8c, 0x62, 0xc6, 0xf0, 0x67, 0x20, 0xa3, 0x63, 0xa1, 0x25, 0x26, - 0x75, 0xf6, 0xe2, 0xed, 0x8d, 0xbc, 0xaa, 0x0b, 0xe4, 0x0d, 0x86, 0xc0, 0x61, 0x80, 0x61, 0xb0, - 0x0e, 0x20, 0x23, 0x54, 0x06, 0x6b, 0x9f, 0x7a, 0x7b, 0x4e, 0x9b, 0x88, 0x86, 0x21, 0x25, 0x1b, - 0x06, 0x79, 0xc5, 0xf8, 0x48, 0x69, 0x77, 0x94, 0x72, 0xb3, 0x81, 0x0a, 0x6c, 0x58, 0x62, 0xc3, - 0x3b, 0xe0, 0x8a, 0xbe, 0xbd, 0xb6, 0x84, 0x8e, 0x50, 0x79, 0xdb, 0x4d, 0x18, 0x93, 0xa9, 0x37, - 0x8d, 0x16, 0xb4, 0xf6, 0x91, 0x54, 0xd6, 0x94, 0x0e, 0xfe, 0x10, 0x2c, 0xc6, 0x03, 0xd4, 0x88, - 0x25, 0x90, 0x96, 0x66, 0x0c, 0x31, 0x6c, 0x5d, 0x05, 0xf3, 0xf2, 0x58, 0x8e, 0x98, 0x65, 0xa4, - 0x59, 0x51, 0xa8, 0x86, 0xf1, 0xf7, 0x41, 0xba, 0xed, 0x29, 0x22, 0x66, 0x66, 0xe5, 0x7a, 0x54, - 0x4e, 0x5f, 0x8f, 0xad, 0x00, 0xaa, 0x96, 0x23, 0x32, 0x9d, 0xd8, 0x06, 0xcd, 0x9d, 0xbb, 0x0d, - 0xca, 0x4d, 0x6c, 0x83, 0x26, 0x64, 0xbd, 0xfc, 0x37, 0xd9, 0x6f, 0x16, 0xbe, 0xe9, 0x7e, 0xb3, - 0x78, 0x81, 0x7e, 0xf3, 0xf4, 0x1e, 0x10, 0xfe, 0xbf, 0xf4, 0x80, 0xf3, 0xe7, 0xe9, 0x01, 0x17, - 0xce, 0xd1, 0x03, 0x5e, 0x3e, 0x5f, 0x0f, 0x78, 0xe5, 0xab, 0xf6, 0x80, 0x57, 0xcf, 0xdd, 0x03, - 0x9a, 0xa7, 0xf4, 0x80, 0xef, 0x82, 0x34, 0xf5, 0x3c, 0x6e, 0xc9, 0x30, 0xff, 0x8a, 0x9c, 0x5d, - 0x73, 0xac, 0x94, 0xf5, 0x3c, 0x2e, 0x62, 0x3c, 0x4a, 0x51, 0xfd, 0x04, 0x9f, 0x82, 0x19, 0x97, - 0x70, 0xb1, 0xae, 0x8b, 0x32, 0xf1, 0xdc, 0xfb, 0x53, 0xbf, 0xbc, 0x76, 0xa1, 0xdf, 0xae, 0xb6, - 0x09, 0xdf, 0x6c, 0x0c, 0xfa, 0xe5, 0x4b, 0xf2, 0x01, 0x5d, 0x72, 0x09, 0x97, 0x77, 0x4d, 0x59, - 0xb1, 0xe2, 0x4c, 0x57, 0xf7, 0xe6, 0xab, 0x93, 0x13, 0x4f, 0xac, 0x01, 0x50, 0x3f, 0x06, 0xc4, - 0x04, 0x28, 0xd3, 0xc1, 0xcd, 0xb0, 0xdd, 0x5c, 0x07, 0x69, 0x49, 0x28, 0x92, 0xbb, 0x79, 0x6d, - 0xf2, 0xf8, 0x82, 0xe4, 0x5f, 0xcf, 0x0e, 0xfa, 0xe5, 0xb0, 0xb4, 0x46, 0x29, 0xc1, 0x23, 0x8b, - 0xec, 0x5b, 0x60, 0x96, 0xa9, 0x54, 0x67, 0xbe, 0x26, 0x29, 0xae, 0x9e, 0x92, 0x09, 0x51, 0x80, - 0x83, 0xef, 0x81, 0xa0, 0x20, 0xb1, 0x02, 0xd3, 0xd2, 0xd9, 0xa6, 0x39, 0x8d, 0x0f, 0x7e, 0x24, - 0xbc, 0x01, 0x72, 0x61, 0xfd, 0x28, 0x17, 0xd1, 0x2c, 0xcb, 0xaa, 0x31, 0xab, 0xab, 0x46, 0xb9, - 0x80, 0xf0, 0x4d, 0x90, 0xef, 0x32, 0x62, 0x47, 0x28, 0x66, 0x2e, 0x2d, 0x4d, 0x55, 0xe6, 0xe4, - 0xd6, 0xb1, 0x03, 0x18, 0x13, 0x38, 0xc9, 0x16, 0xed, 0x09, 0xf3, 0xf5, 0xe8, 0xf7, 0xb8, 0x70, - 0x43, 0xc0, 0xef, 0x6a, 0x1c, 0xfd, 0x44, 0x37, 0x8a, 0x37, 0xcd, 0x65, 0xf9, 0x9b, 0x4b, 0x61, - 0xd0, 0x2f, 0x67, 0xb7, 0x30, 0xe3, 0xe8, 0x43, 0xd9, 0x04, 0xde, 0x54, 0x8e, 0xa0, 0x4f, 0xd4, - 0xdb, 0xb8, 0xe1, 0x2d, 0xf3, 0xfa, 0x44, 0xc3, 0x5b, 0x43, 0x86, 0xb7, 0xe0, 0xc7, 0xe0, 0xd5, - 0xd1, 0x3a, 0x99, 0x92, 0x26, 0x71, 0x0e, 0x55, 0x8a, 0xbe, 0x71, 0x91, 0x3a, 0x3c, 0x2c, 0xa6, - 0x91, 0x66, 0xa8, 0x89, 0x13, 0x97, 0x51, 0xbf, 0x72, 0xa9, 0x3d, 0xf0, 0xc6, 0x29, 0x81, 0x4e, - 0x40, 0xd4, 0xba, 0x03, 0x3f, 0x7c, 0x86, 0x2b, 0x00, 0xee, 0xca, 0xeb, 0x8c, 0x63, 0x51, 0x8b, - 0x37, 0x89, 0xcb, 0x71, 0x8b, 0x98, 0x6f, 0x2e, 0x19, 0x95, 0x24, 0x2a, 0x6a, 0xcd, 0x4e, 0xa8, - 0x80, 0xdf, 0x02, 0xf9, 0xb0, 0x87, 0xd0, 0x17, 0x14, 0xdf, 0x5a, 0x32, 0x2a, 0x97, 0x50, 0x2e, - 0x10, 0xeb, 0x9b, 0x07, 0x2c, 0x0e, 0xa9, 0xb0, 0xb2, 0xb0, 0x4d, 0xf5, 0x75, 0x36, 0x33, 0x2b, - 0x32, 0x07, 0x8d, 0x45, 0x37, 0x75, 0xb3, 0xad, 0x2f, 0x60, 0x54, 0x06, 0x46, 0xd2, 0xb8, 0xd6, - 0x40, 0x4a, 0xc7, 0xc4, 0xc9, 0x96, 0x12, 0x9b, 0x6a, 0x09, 0x6c, 0x80, 0x9c, 0xfe, 0x44, 0x40, - 0xff, 0xd6, 0x39, 0xe8, 0xd1, 0x9c, 0x32, 0x0a, 0x58, 0x3e, 0x04, 0x9a, 0x39, 0xec, 0x16, 0x98, - 0xf9, 0xb6, 0xe4, 0x29, 0x8f, 0x35, 0xab, 0xc1, 0x10, 0x35, 0x53, 0x5e, 0x19, 0x06, 0x62, 0x26, - 0xda, 0x10, 0x5d, 0x91, 0x4f, 0xea, 0x42, 0x98, 0xf9, 0x6d, 0xc9, 0x7b, 0xbe, 0x36, 0x44, 0x11, - 0x4d, 0x50, 0x31, 0xf8, 0x01, 0x00, 0xb1, 0xeb, 0xac, 0x77, 0x2e, 0x76, 0x9d, 0x85, 0x62, 0xb6, - 0x10, 0x83, 0x9c, 0x4f, 0xbd, 0x43, 0x47, 0x9c, 0x47, 0x42, 0x45, 0xb4, 0x5b, 0x91, 0x59, 0xec, - 0xae, 0x88, 0xd4, 0x3b, 0x91, 0xe6, 0x22, 0xb7, 0xe0, 0x73, 0x31, 0xc6, 0x4d, 0x1b, 0x36, 0x40, - 0x31, 0x14, 0x88, 0x60, 0x61, 0x63, 0x8e, 0xcd, 0xaa, 0x8e, 0x14, 0xa3, 0x7b, 0xfe, 0x91, 0xfc, - 0xbf, 0x0a, 0x54, 0x88, 0x5b, 0x34, 0x30, 0xc7, 0x8b, 0x3f, 0x02, 0xf9, 0x91, 0x72, 0x11, 0x16, - 0xc0, 0xd4, 0x01, 0x51, 0xbf, 0x0a, 0xa5, 0x91, 0x78, 0x84, 0x0b, 0xc1, 0x65, 0x83, 0xfa, 0x91, - 0x43, 0xbd, 0xdc, 0x4d, 0x7e, 0xcf, 0x58, 0x7c, 0x0a, 0x72, 0xc3, 0xd5, 0xcd, 0x04, 0xeb, 0x6a, - 0xdc, 0x7a, 0x42, 0x10, 0x0d, 0x08, 0x62, 0xbc, 0xba, 0x0f, 0xf8, 0x00, 0x80, 0xb0, 0x8a, 0x62, - 0xf0, 0x2e, 0xc8, 0x44, 0xff, 0x17, 0x23, 0xfa, 0x81, 0x29, 0x79, 0xab, 0x75, 0x5a, 0xd9, 0x85, - 0x00, 0x09, 0x6d, 0x97, 0x7f, 0x06, 0xae, 0xac, 0xcb, 0x4a, 0x3e, 0x52, 0xeb, 0x46, 0xa5, 0x0e, - 0x40, 0xc4, 0xaa, 0x9b, 0x8c, 0xd3, 0x49, 0x63, 0x9d, 0x45, 0x3a, 0xa4, 0x5f, 0xfe, 0x57, 0x03, - 0x5c, 0x79, 0x22, 0x6b, 0xfc, 0x6f, 0x82, 0x1e, 0xde, 0x03, 0x20, 0xfa, 0xcf, 0x99, 0x53, 0xdb, - 0x97, 0xfb, 0x02, 0xf2, 0x00, 0xb3, 0x03, 0xdd, 0x50, 0xa5, 0xf7, 0x02, 0xc1, 0xf2, 0x7f, 0x19, - 0x60, 0xfe, 0x7d, 0xc2, 0xc7, 0x9c, 0x7b, 0x0c, 0x72, 0x91, 0x73, 0xd6, 0x57, 0x6f, 0xb2, 0xb2, - 0x24, 0xd2, 0xb3, 0xaf, 0xef, 0xee, 0xff, 0x18, 0xe0, 0xf2, 0x96, 0xc3, 0x22, 0x7f, 0x59, 0xe0, - 0xf0, 0x47, 0x20, 0x1f, 0x0f, 0x00, 0x91, 0xc7, 0x6f, 0x9e, 0x71, 0xf4, 0x27, 0xfb, 0x9c, 0xc3, - 0x71, 0xc4, 0xd7, 0xf7, 0x5a, 0x1c, 0x12, 0x8f, 0xda, 0x84, 0xea, 0x1f, 0xa4, 0xd4, 0x8b, 0xfc, - 0xbd, 0x4f, 0xfe, 0xd3, 0x82, 0xfa, 0xa7, 0x18, 0xf5, 0x22, 0xda, 0x40, 0x5f, 0xa4, 0x03, 0xf5, - 0x2f, 0x30, 0xf2, 0x79, 0xf9, 0x57, 0x06, 0x98, 0x7f, 0x34, 0x61, 0x91, 0xbe, 0x0b, 0x66, 0xce, - 0xbb, 0x7b, 0x94, 0x4f, 0x1a, 0xfe, 0xb5, 0x47, 0xf4, 0xf6, 0x7d, 0x00, 0xa2, 0xe4, 0x06, 0x8b, - 0x60, 0x6e, 0xe7, 0xe1, 0xb3, 0x0d, 0x64, 0x3d, 0xd9, 0xfe, 0xf1, 0xf6, 0xc3, 0x67, 0xdb, 0x85, - 0x44, 0x24, 0xaa, 0xd7, 0x1e, 0x3f, 0xde, 0x40, 0x1f, 0x15, 0x0c, 0x08, 0x41, 0x4e, 0x89, 0x36, - 0xfe, 0xf6, 0xf1, 0x06, 0xda, 0xae, 0x6d, 0x15, 0x92, 0xf5, 0x7f, 0x33, 0x3e, 0x7b, 0x59, 0x32, - 0x3e, 0x7f, 0x59, 0x32, 0xfe, 0xf8, 0xb2, 0x94, 0xf8, 0xf3, 0xcb, 0x52, 0xe2, 0x2f, 0x2f, 0x4b, - 0x89, 0xbf, 0xbe, 0x2c, 0x25, 0xbe, 0x78, 0x59, 0x32, 0x7e, 0x31, 0x28, 0x19, 0xbf, 0x1c, 0x94, - 0x12, 0xbf, 0x1b, 0x94, 0x8c, 0xdf, 0x0f, 0x4a, 0x89, 0x4f, 0x07, 0xa5, 0xc4, 0x1f, 0x06, 0xa5, - 0xc4, 0x67, 0x83, 0x92, 0xf1, 0xf9, 0xa0, 0x64, 0xfc, 0x71, 0x50, 0x4a, 0xfc, 0x79, 0x50, 0x32, - 0xfe, 0x32, 0x28, 0x25, 0xfe, 0x3a, 0x28, 0x19, 0x5f, 0x0c, 0x4a, 0x89, 0x5f, 0x9c, 0x94, 0x12, - 0xbf, 0x3c, 0x29, 0x19, 0xbf, 0x3e, 0x29, 0x25, 0x7e, 0x73, 0x52, 0x32, 0x7e, 0x7b, 0x52, 0x4a, - 0xfc, 0xee, 0xa4, 0x94, 0xf8, 0xfd, 0x49, 0xc9, 0xf8, 0xf4, 0xa4, 0x64, 0xfc, 0xe1, 0xa4, 0x64, - 0xfc, 0xe4, 0x9d, 0xf3, 0x56, 0x95, 0xdc, 0xf5, 0x77, 0x77, 0x67, 0xe4, 0x8c, 0xdc, 0xfe, 0xdf, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xd3, 0xf1, 0xbd, 0x62, 0x8e, 0x27, 0x00, 0x00, + golang_proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_7df2e0db88789f5d) +} + +var fileDescriptor_end_device_7df2e0db88789f5d = []byte{ + // 3729 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0x4b, 0x70, 0x1b, 0xc7, + 0x99, 0x06, 0x40, 0x8a, 0x04, 0x1a, 0x24, 0x1e, 0xcd, 0x87, 0xc6, 0x94, 0x0c, 0xd0, 0x94, 0xec, + 0xd0, 0x8e, 0x09, 0x4a, 0x94, 0xbc, 0x89, 0x15, 0xa7, 0x64, 0x80, 0xa0, 0x6c, 0xda, 0x14, 0xc5, + 0x6d, 0x52, 0xd2, 0xda, 0xb1, 0x3c, 0xd5, 0xc4, 0x34, 0xc9, 0x31, 0x81, 0x99, 0x49, 0x77, 0x83, + 0x04, 0xf7, 0x51, 0x95, 0x63, 0x6e, 0xc9, 0x65, 0xab, 0x72, 0xd9, 0xaa, 0xd4, 0xd6, 0x6e, 0x55, + 0x6a, 0x6b, 0x0f, 0x39, 0xed, 0xfa, 0x98, 0xa3, 0x6f, 0xeb, 0x63, 0x2a, 0x07, 0x38, 0x02, 0x2f, + 0x39, 0xa6, 0x6a, 0x2f, 0x3e, 0x6e, 0xf5, 0x63, 0x1e, 0x78, 0x51, 0xa0, 0xbc, 0xbe, 0xb0, 0x30, + 0xff, 0xe3, 0xeb, 0xbf, 0x5f, 0x7f, 0x7f, 0xfd, 0x37, 0xc1, 0x52, 0xdd, 0xa5, 0xf8, 0x14, 0x3b, + 0x2b, 0x8c, 0xe3, 0xda, 0xf1, 0x2a, 0xf6, 0xec, 0x55, 0xe2, 0x58, 0xa6, 0x45, 0x4e, 0xec, 0x1a, + 0x29, 0x79, 0xd4, 0xe5, 0x2e, 0xcc, 0x70, 0xee, 0x94, 0xb4, 0x5d, 0xe9, 0xe4, 0xce, 0xc2, 0xca, + 0xa1, 0xcd, 0x8f, 0x9a, 0xfb, 0xa5, 0x9a, 0xdb, 0x58, 0x3d, 0x74, 0x0f, 0xdd, 0x55, 0x69, 0xb6, + 0xdf, 0x3c, 0x90, 0x5f, 0xf2, 0x43, 0xfe, 0x52, 0xee, 0x0b, 0x7f, 0x13, 0x31, 0x6f, 0x9c, 0xda, + 0xfc, 0xd8, 0x3d, 0x5d, 0x3d, 0x74, 0x57, 0xa4, 0x72, 0xe5, 0x04, 0xd7, 0x6d, 0x0b, 0x73, 0x97, + 0xb2, 0xd5, 0xe0, 0xa7, 0xf6, 0xbb, 0x7e, 0xe8, 0xba, 0x87, 0x75, 0x22, 0x63, 0xc2, 0x8e, 0xe3, + 0x72, 0xcc, 0x6d, 0xd7, 0x61, 0x5a, 0x5b, 0xd0, 0xda, 0xa0, 0x6d, 0xab, 0x49, 0xa5, 0x81, 0xd6, + 0x2f, 0xf6, 0xea, 0x0f, 0x6c, 0x52, 0xb7, 0xcc, 0x06, 0x66, 0xc7, 0x3d, 0xf8, 0x81, 0x05, 0xe3, + 0xb4, 0x59, 0xe3, 0x5a, 0x5b, 0xec, 0xd5, 0x72, 0xbb, 0x41, 0x18, 0xc7, 0x0d, 0x6f, 0x58, 0x00, + 0xa7, 0x14, 0x7b, 0x1e, 0xa1, 0x7e, 0x80, 0x37, 0xfa, 0x47, 0xd6, 0xb6, 0x88, 0xc3, 0xed, 0x03, + 0x3b, 0x34, 0xba, 0xde, 0x6f, 0xf4, 0x85, 0x6b, 0x3b, 0xc3, 0xb5, 0xc7, 0xe4, 0xcc, 0xf7, 0x2d, + 0xf6, 0x6b, 0xfd, 0x49, 0xd2, 0x43, 0xd0, 0x6f, 0xd0, 0x20, 0x8c, 0xe1, 0x43, 0xc2, 0x2e, 0xb2, + 0xe0, 0xd8, 0xc2, 0x1c, 0x2b, 0x8b, 0xa5, 0x5f, 0x8d, 0x81, 0xc9, 0x5d, 0xc2, 0x98, 0xed, 0x3a, + 0xf0, 0x29, 0x48, 0x5a, 0xe4, 0xc4, 0xc4, 0x96, 0x45, 0x8d, 0xc4, 0x62, 0x7c, 0x79, 0xaa, 0xf2, + 0xde, 0x57, 0xed, 0x62, 0xec, 0x4f, 0xed, 0xe2, 0xdd, 0x43, 0xb7, 0xc4, 0x8f, 0x08, 0x3f, 0xb2, + 0x9d, 0x43, 0x56, 0x72, 0x08, 0x3f, 0x75, 0xe9, 0xf1, 0x6a, 0x37, 0xb8, 0x77, 0x7c, 0xb8, 0xca, + 0xcf, 0x3c, 0xc2, 0x4a, 0x55, 0x72, 0x52, 0xb6, 0x2c, 0x8a, 0x26, 0x2d, 0xf5, 0x03, 0xbe, 0x0b, + 0xc6, 0x45, 0xbf, 0x8c, 0xb1, 0xc5, 0xf8, 0x72, 0x7a, 0xed, 0x5a, 0xa9, 0x7b, 0xbd, 0x95, 0x74, + 0xfb, 0x1f, 0x93, 0x33, 0x56, 0x49, 0x8a, 0x16, 0xbf, 0x6e, 0x17, 0xe3, 0x48, 0xba, 0xc0, 0xd7, + 0xc0, 0x74, 0x1d, 0x33, 0x6e, 0x1e, 0x98, 0x35, 0x87, 0x9b, 0x4d, 0xcf, 0x18, 0x5f, 0x8c, 0x2f, + 0x4f, 0x23, 0x20, 0x84, 0x0f, 0xd6, 0x1d, 0xfe, 0xd8, 0x83, 0xcb, 0x20, 0x2f, 0x4d, 0x1c, 0x6d, + 0x64, 0xb9, 0xa7, 0x8e, 0x71, 0x45, 0x9a, 0x49, 0xdf, 0x6d, 0x61, 0x57, 0x75, 0x4f, 0x9d, 0xc0, + 0x12, 0x47, 0x2d, 0x27, 0x42, 0xcb, 0x72, 0x60, 0x59, 0x02, 0xb3, 0xd2, 0xb2, 0xe6, 0x3a, 0x07, + 0x51, 0xe3, 0x49, 0x69, 0x9c, 0x13, 0xba, 0x75, 0xd7, 0x39, 0x08, 0xec, 0xd7, 0x01, 0x60, 0x1c, + 0x53, 0x4e, 0x2c, 0x13, 0x73, 0x23, 0x29, 0xfb, 0xb9, 0x50, 0x52, 0x2b, 0xa8, 0xe4, 0xaf, 0xa0, + 0xd2, 0x9e, 0xbf, 0xc4, 0x54, 0x37, 0x7f, 0xfd, 0x4d, 0x31, 0x8e, 0x52, 0xda, 0xaf, 0xcc, 0x3f, + 0x1a, 0x4f, 0xc6, 0x73, 0x89, 0xa5, 0x6f, 0xd2, 0x60, 0xfa, 0x61, 0x79, 0x7d, 0x07, 0x53, 0xdc, + 0x20, 0x9c, 0x50, 0x06, 0xdf, 0x00, 0xc9, 0x06, 0x6e, 0x99, 0xc4, 0xa6, 0x9e, 0x11, 0x5f, 0x8c, + 0x2f, 0x27, 0x2a, 0xe9, 0x4e, 0xbb, 0x38, 0xf9, 0x10, 0xb7, 0x36, 0x36, 0xd1, 0x0e, 0x9a, 0x6c, + 0xe0, 0xd6, 0x86, 0x4d, 0x3d, 0xf8, 0x16, 0xc8, 0x37, 0xbd, 0xba, 0xed, 0x1c, 0x9b, 0xd6, 0x29, + 0xa9, 0xd7, 0x4d, 0xb1, 0xa2, 0xe5, 0x44, 0x26, 0x51, 0x56, 0x29, 0xaa, 0x42, 0x2e, 0xa2, 0x80, + 0x25, 0x30, 0x23, 0x3a, 0xd4, 0x6b, 0x3d, 0x26, 0xad, 0xf3, 0xbe, 0x2a, 0xb4, 0xdf, 0x07, 0x33, + 0xd8, 0xa2, 0xa6, 0x58, 0x39, 0x26, 0xc5, 0x9c, 0x98, 0xb6, 0x63, 0x91, 0x96, 0x9c, 0x8d, 0xcc, + 0xda, 0xab, 0xbd, 0x33, 0x5a, 0xc5, 0x1c, 0x23, 0xcc, 0xc9, 0xa6, 0x30, 0xaa, 0xcc, 0x76, 0xda, + 0xc5, 0x5c, 0xb9, 0x8a, 0xba, 0xa4, 0x28, 0x87, 0x2d, 0xda, 0x25, 0x81, 0xef, 0x03, 0x28, 0xda, + 0xe0, 0x2d, 0xd3, 0x73, 0x4f, 0x09, 0xd5, 0x4d, 0xc8, 0x99, 0xac, 0xcc, 0x74, 0xda, 0xc5, 0x6c, + 0xb9, 0x8a, 0xf6, 0x5a, 0x3b, 0x42, 0xa7, 0x20, 0xb2, 0xd8, 0xa2, 0x51, 0x01, 0xbc, 0x05, 0xa6, + 0x04, 0x82, 0xb3, 0x6f, 0x72, 0x8a, 0x1d, 0xa6, 0xe6, 0xb6, 0x92, 0xe9, 0xb4, 0x8b, 0xa0, 0x5c, + 0x45, 0xdb, 0xfb, 0x7b, 0x42, 0x8a, 0x00, 0xb6, 0xa8, 0xfe, 0x0d, 0xef, 0x80, 0x69, 0xe1, 0x81, + 0x6b, 0xc7, 0x66, 0xdd, 0x6e, 0xd8, 0x5c, 0xcd, 0x70, 0x25, 0xdb, 0x69, 0x17, 0xd3, 0xe5, 0x2a, + 0x2a, 0xd7, 0x8e, 0xb7, 0x84, 0x18, 0xa5, 0xb1, 0x45, 0xfd, 0x8f, 0xa8, 0x93, 0x45, 0xea, 0xf8, + 0x4c, 0x4e, 0x78, 0x97, 0x53, 0x55, 0x88, 0x7d, 0x27, 0xf9, 0x01, 0xef, 0x82, 0x14, 0x6d, 0xdd, + 0xd6, 0x0e, 0x29, 0x39, 0x6e, 0x57, 0x7b, 0xc7, 0x0d, 0xb5, 0x94, 0x63, 0x92, 0xb6, 0x6e, 0x2b, + 0xaf, 0x55, 0x30, 0x2b, 0xbd, 0x82, 0x71, 0x77, 0x0f, 0x0e, 0x18, 0xe1, 0x06, 0x90, 0x0b, 0x31, + 0x2f, 0xec, 0xf4, 0x18, 0x3e, 0x92, 0x0a, 0xb8, 0x05, 0x66, 0x68, 0x6b, 0xad, 0x6f, 0xa2, 0xd2, + 0x23, 0x4c, 0x14, 0xca, 0xd1, 0xd6, 0x5a, 0xf7, 0x94, 0xdc, 0x00, 0xd3, 0x02, 0xed, 0x80, 0x92, + 0x9f, 0x37, 0x89, 0x53, 0x3b, 0x33, 0xa6, 0x16, 0xe3, 0xcb, 0xe3, 0x68, 0x8a, 0xb6, 0xd6, 0x1e, + 0xf8, 0x32, 0xb8, 0x09, 0x32, 0x62, 0x7d, 0x5a, 0x4d, 0x7e, 0x66, 0xd6, 0xce, 0x6a, 0x75, 0x62, + 0x4c, 0xcb, 0xd6, 0x6e, 0xf4, 0xb6, 0x56, 0x3e, 0x3c, 0xa4, 0xe4, 0x10, 0x73, 0x62, 0x55, 0x9b, + 0xfc, 0x6c, 0x5d, 0x98, 0xa2, 0xa9, 0x06, 0x6e, 0x05, 0x5f, 0xf0, 0x53, 0x70, 0x95, 0x12, 0x91, + 0x21, 0xe5, 0x72, 0x34, 0x3d, 0x42, 0x6d, 0xd7, 0xb2, 0x6b, 0x36, 0x3f, 0x33, 0x32, 0x12, 0x73, + 0xa9, 0x6f, 0xc8, 0xa4, 0xb9, 0x58, 0xa3, 0x1b, 0x2d, 0xcf, 0x75, 0x88, 0xc3, 0xd1, 0x1c, 0x0d, + 0x64, 0x3b, 0x21, 0x00, 0x7c, 0x06, 0x0c, 0x8d, 0x5d, 0x73, 0x9b, 0x0e, 0xef, 0x02, 0xcf, 0x0e, + 0x0e, 0x58, 0x81, 0xaf, 0x0b, 0xf3, 0x00, 0x7d, 0x9e, 0x86, 0xc2, 0x28, 0x7c, 0x09, 0xcc, 0x78, + 0xb6, 0x73, 0x68, 0xb2, 0xba, 0xcb, 0x23, 0x03, 0x96, 0x93, 0x03, 0x96, 0x17, 0xaa, 0xdd, 0xba, + 0xcb, 0xc3, 0x51, 0x7b, 0x0a, 0x5e, 0x09, 0xed, 0x7b, 0xa7, 0x2b, 0x3f, 0xca, 0x74, 0xcd, 0xf9, + 0xa0, 0xdd, 0x73, 0xf6, 0x26, 0xc8, 0xed, 0x13, 0x5c, 0x73, 0x9d, 0x48, 0x14, 0x50, 0x46, 0x91, + 0x55, 0xf2, 0x30, 0x86, 0x32, 0x48, 0xd6, 0x8e, 0xb0, 0xe3, 0x90, 0x3a, 0x33, 0x66, 0x16, 0xc7, + 0x96, 0xd3, 0x6b, 0xaf, 0xf7, 0x36, 0xd9, 0x95, 0x8a, 0x4a, 0xeb, 0xca, 0x1a, 0x05, 0x6e, 0x0b, + 0xff, 0x91, 0x00, 0x93, 0x5a, 0x2a, 0x5a, 0xd6, 0x09, 0x28, 0x6c, 0x39, 0xae, 0x5a, 0x56, 0xf2, + 0xb0, 0xe5, 0x15, 0x00, 0x83, 0xfc, 0x13, 0x1a, 0x27, 0xd4, 0x60, 0xf9, 0x9a, 0xd0, 0x7c, 0x0b, + 0xcc, 0x34, 0x6c, 0xa7, 0x6f, 0x98, 0xc6, 0x46, 0x5a, 0xd5, 0x0d, 0xdb, 0xe9, 0x1e, 0x21, 0x81, + 0x26, 0x16, 0xec, 0x4b, 0x24, 0x33, 0x94, 0x13, 0xeb, 0xb5, 0x77, 0x8f, 0x10, 0x07, 0xef, 0xd7, + 0x89, 0xa9, 0x3a, 0x29, 0x33, 0x56, 0x12, 0x4d, 0x29, 0xe1, 0x63, 0x29, 0xbb, 0x37, 0xfe, 0xe5, + 0x6f, 0x8b, 0x31, 0xf5, 0x77, 0xa9, 0x01, 0x32, 0x1b, 0x8e, 0x55, 0x95, 0x14, 0xac, 0x42, 0xb1, + 0x63, 0xc1, 0x79, 0x90, 0xb0, 0x2d, 0x39, 0x54, 0xa9, 0xca, 0x44, 0xa7, 0x5d, 0x4c, 0x6c, 0x56, + 0x51, 0xc2, 0xb6, 0x20, 0x04, 0xe3, 0x0e, 0xd6, 0x49, 0x3c, 0x85, 0xe4, 0x6f, 0xf8, 0x0a, 0x18, + 0x6b, 0xd2, 0xba, 0xec, 0x7a, 0xaa, 0x32, 0xd9, 0x69, 0x17, 0xc7, 0x1e, 0xa3, 0x2d, 0x24, 0x64, + 0x70, 0x16, 0x5c, 0xa9, 0xbb, 0x87, 0x2e, 0x33, 0xc6, 0x17, 0xc7, 0x96, 0x53, 0x48, 0x7d, 0x2c, + 0x59, 0x91, 0xe6, 0x1e, 0xba, 0x16, 0xa9, 0x8b, 0x03, 0x65, 0x5f, 0xb4, 0x6b, 0x06, 0x8d, 0xca, + 0x03, 0x45, 0xc6, 0xb2, 0x59, 0x45, 0x93, 0x52, 0xb9, 0xe9, 0x87, 0x95, 0x18, 0x1a, 0xd6, 0x58, + 0x18, 0xd6, 0xd2, 0x3f, 0x27, 0xc0, 0xb5, 0xa0, 0x99, 0x27, 0x84, 0x8a, 0x13, 0x7d, 0x33, 0xe4, + 0x43, 0xf0, 0x51, 0x5f, 0x9b, 0x77, 0x23, 0x6d, 0x76, 0xbe, 0x29, 0xbe, 0x0e, 0x5e, 0xfb, 0xfc, + 0x67, 0x78, 0xe5, 0xef, 0x6f, 0xad, 0xbc, 0xfb, 0x6c, 0xf9, 0xfe, 0xbd, 0x9f, 0xad, 0x3c, 0xbb, + 0xef, 0x7f, 0xbe, 0xf9, 0x0f, 0x6b, 0x6f, 0xff, 0xd3, 0xcd, 0x7f, 0xfc, 0xfc, 0x66, 0xeb, 0xf5, + 0x30, 0xb8, 0x47, 0x20, 0xd9, 0x10, 0xbd, 0x31, 0x83, 0x10, 0x25, 0xa0, 0xec, 0xe1, 0xa5, 0x00, + 0x25, 0xca, 0xa6, 0x25, 0x56, 0xef, 0x11, 0xa6, 0xd6, 0x29, 0xa6, 0xc4, 0x3c, 0x51, 0x1d, 0xd0, + 0x3d, 0xcc, 0xfa, 0x72, 0xdd, 0x2f, 0x61, 0x7a, 0x60, 0xd3, 0x46, 0x97, 0xe9, 0xb8, 0x32, 0xf5, + 0xe5, 0xda, 0x74, 0xe9, 0x7f, 0x26, 0x40, 0xae, 0x77, 0x5c, 0xe0, 0x07, 0x60, 0xcc, 0xb6, 0x98, + 0x1c, 0x87, 0xf4, 0xda, 0x0f, 0x7b, 0x17, 0xdc, 0x05, 0xc3, 0x18, 0xe1, 0x47, 0x02, 0x01, 0x3e, + 0x05, 0x59, 0xed, 0x18, 0xc4, 0x91, 0x90, 0xab, 0x78, 0x61, 0xc0, 0x3e, 0xd6, 0x70, 0x15, 0xd8, + 0x69, 0x17, 0x33, 0x5b, 0x2e, 0xc2, 0x4f, 0xcb, 0xdb, 0x5a, 0x86, 0x32, 0xda, 0xd4, 0x8f, 0x10, + 0x83, 0x19, 0x1f, 0xd8, 0x3b, 0x3a, 0xeb, 0x1a, 0x8f, 0x01, 0xe0, 0x3b, 0x1f, 0x7e, 0xe2, 0x83, + 0xcf, 0x75, 0xda, 0xc5, 0xbc, 0x06, 0x0f, 0xc5, 0x28, 0xaf, 0xad, 0x77, 0x8e, 0xce, 0xfc, 0x26, + 0xee, 0x83, 0x7c, 0xb0, 0xf3, 0x4d, 0xaf, 0x8e, 0x1d, 0x31, 0x93, 0x72, 0x14, 0xd5, 0x69, 0x1f, + 0xec, 0xfe, 0x9d, 0x3a, 0x76, 0x36, 0xab, 0x28, 0x7b, 0xd0, 0x25, 0x10, 0xcb, 0x73, 0xc2, 0x3b, + 0x72, 0xb9, 0xcb, 0x8c, 0x2b, 0x72, 0xbd, 0xeb, 0x2f, 0xb8, 0x0c, 0x72, 0xac, 0xe9, 0x79, 0x2e, + 0xe5, 0xcc, 0xac, 0xd5, 0x31, 0x63, 0xe6, 0xbe, 0x64, 0x02, 0x49, 0x94, 0xf1, 0xe5, 0xeb, 0x42, + 0x5c, 0x19, 0x60, 0x59, 0x93, 0x04, 0xa0, 0xd7, 0x72, 0x1d, 0x12, 0x30, 0x6b, 0x91, 0x03, 0xdc, + 0xac, 0x73, 0xb3, 0x81, 0x6b, 0x26, 0x23, 0x9c, 0x0b, 0x2e, 0xac, 0xa9, 0xde, 0xb5, 0x01, 0xa3, + 0xbd, 0xab, 0x4d, 0x2a, 0xf3, 0x9d, 0x76, 0x11, 0x56, 0x95, 0x73, 0x44, 0x8e, 0xa0, 0x06, 0x7c, + 0x88, 0x6b, 0xbe, 0x4c, 0xe4, 0x12, 0x91, 0xe7, 0xc2, 0x8c, 0x98, 0x52, 0xe7, 0x6d, 0xc3, 0x8e, + 0x64, 0x6d, 0x61, 0x84, 0x5b, 0x11, 0x23, 0xa0, 0x8d, 0x70, 0x2b, 0x34, 0x5a, 0x04, 0x53, 0x94, + 0x30, 0xc2, 0x99, 0xa2, 0xaf, 0x92, 0x00, 0x24, 0x11, 0x50, 0x32, 0xc1, 0x5b, 0x05, 0x4c, 0xd0, + 0x79, 0x71, 0xa2, 0xc9, 0x53, 0x3b, 0x89, 0xa6, 0x7c, 0xe1, 0x47, 0xae, 0xed, 0xc0, 0xb7, 0x01, + 0xd4, 0x30, 0xf2, 0xe4, 0x74, 0x5c, 0xa7, 0x46, 0x98, 0x3c, 0x8b, 0x93, 0x28, 0xa7, 0x34, 0xc2, + 0x6e, 0x5b, 0xca, 0xe1, 0x33, 0xe0, 0x77, 0xca, 0x3c, 0x70, 0x69, 0x03, 0x73, 0x71, 0x68, 0xc8, + 0xc3, 0x35, 0xbd, 0xb6, 0xdc, 0x37, 0x46, 0xea, 0xae, 0xb2, 0x83, 0xcf, 0xea, 0x2e, 0xb6, 0x1e, + 0x04, 0xf6, 0x95, 0x71, 0xb1, 0xc6, 0x51, 0x5e, 0x23, 0x85, 0x0a, 0x9d, 0x3e, 0xff, 0x2b, 0x0b, + 0xd2, 0x91, 0x71, 0x84, 0x1f, 0x80, 0xac, 0x9e, 0x65, 0x49, 0x1a, 0xdc, 0x26, 0xd7, 0x1b, 0xeb, + 0x95, 0x3e, 0x02, 0x5e, 0xd5, 0x77, 0xc8, 0xca, 0xf8, 0x6f, 0x04, 0xf7, 0x9e, 0x96, 0x7e, 0x95, + 0x3d, 0xe5, 0x05, 0x6b, 0x60, 0x2e, 0x3c, 0x91, 0xa3, 0xec, 0x20, 0x21, 0xe1, 0x56, 0x2f, 0x98, + 0xe4, 0xd2, 0x8e, 0x3e, 0x8a, 0x15, 0x23, 0x78, 0x82, 0xeb, 0x4d, 0x82, 0x66, 0xbc, 0x2e, 0xa1, + 0xa2, 0x09, 0x47, 0x17, 0x1d, 0xfb, 0xea, 0x82, 0x54, 0xba, 0xa8, 0xa1, 0xae, 0xb3, 0x47, 0xb5, + 0x33, 0x84, 0x07, 0x0c, 0x21, 0x24, 0xe3, 0xc3, 0x08, 0x49, 0x30, 0x8e, 0xb5, 0x60, 0x1c, 0xaf, + 0x5c, 0x66, 0x1c, 0xd7, 0xfd, 0x71, 0xdc, 0x88, 0x32, 0xdd, 0x89, 0x21, 0x93, 0x1f, 0xe9, 0x92, + 0x66, 0xbd, 0xaa, 0x33, 0x21, 0xf5, 0x7d, 0x38, 0x84, 0xfa, 0x4e, 0x4a, 0xc4, 0xeb, 0x7d, 0x41, + 0x3d, 0xde, 0x74, 0xf8, 0x9d, 0x35, 0x85, 0x32, 0x80, 0x18, 0x3f, 0x1b, 0x4c, 0x8c, 0x93, 0x2f, + 0x35, 0xe4, 0x23, 0x30, 0xe5, 0xd4, 0x00, 0xa6, 0xfc, 0x1e, 0x58, 0x38, 0xc0, 0x35, 0xee, 0xd2, + 0x33, 0xd3, 0x93, 0x9b, 0x27, 0xb0, 0xb7, 0x09, 0x33, 0xc0, 0xe2, 0xd8, 0xf2, 0x38, 0x32, 0xb4, + 0xc5, 0x8e, 0x34, 0x78, 0x10, 0xea, 0xe1, 0xa7, 0x7d, 0x3c, 0x3b, 0x2d, 0x83, 0xbf, 0x7b, 0x51, + 0xf0, 0x03, 0x38, 0xb7, 0xea, 0x42, 0x37, 0xf1, 0xae, 0x81, 0xb9, 0x20, 0x19, 0xdc, 0x59, 0x33, + 0xf7, 0x6d, 0x7d, 0xe5, 0x96, 0x84, 0x7f, 0xd0, 0x5d, 0xb6, 0xe2, 0xba, 0x75, 0x09, 0xa4, 0x32, + 0xfe, 0xae, 0x76, 0xbe, 0xb3, 0x56, 0xb1, 0xe5, 0xc5, 0x1c, 0xe5, 0x59, 0xaf, 0x08, 0xde, 0x07, + 0x93, 0x4d, 0x46, 0x4c, 0x6c, 0x51, 0x99, 0x6b, 0x2e, 0x86, 0x05, 0x9d, 0x76, 0x71, 0xe2, 0x31, + 0x23, 0xe5, 0x2a, 0x42, 0x13, 0x4d, 0x46, 0xca, 0x16, 0x85, 0x9b, 0x40, 0xdc, 0xdd, 0xcc, 0x06, + 0xa6, 0x87, 0xb6, 0x23, 0xb3, 0x90, 0xc8, 0xbd, 0xbd, 0x18, 0x0f, 0xea, 0x2e, 0xe6, 0x0a, 0x64, + 0xba, 0xd3, 0x2e, 0xa6, 0xca, 0x55, 0xf4, 0x50, 0x7a, 0xa0, 0x14, 0xb6, 0xa8, 0xfa, 0x09, 0xdf, + 0xeb, 0xc9, 0x8f, 0xd9, 0x17, 0x05, 0xd4, 0x95, 0x3b, 0x9f, 0x82, 0xab, 0x8c, 0x63, 0xde, 0x64, + 0xfd, 0xf7, 0x94, 0xdc, 0x68, 0x7b, 0x66, 0x4e, 0xf9, 0xf7, 0x5e, 0x52, 0x9e, 0x00, 0x43, 0x03, + 0xf7, 0x5f, 0x52, 0xf2, 0x23, 0x2c, 0xfc, 0x79, 0xe5, 0xdd, 0x77, 0x3b, 0xd9, 0x03, 0x79, 0x8b, + 0x30, 0x9b, 0x12, 0xcb, 0x0c, 0xf7, 0x26, 0xbc, 0xe4, 0xde, 0xcc, 0x6a, 0x08, 0xe4, 0x6f, 0xd1, + 0xcf, 0xc0, 0xf5, 0x2e, 0xd4, 0xde, 0xad, 0x3a, 0x33, 0x42, 0xc4, 0x46, 0x04, 0xb4, 0x7b, 0xc7, + 0xd6, 0xc1, 0xb5, 0x10, 0xbd, 0x7f, 0xe7, 0xce, 0xbe, 0xd4, 0xce, 0xbd, 0x1a, 0x34, 0xd7, 0xb3, + 0x81, 0xd7, 0xc0, 0x5c, 0xb4, 0xb5, 0x70, 0x23, 0xcf, 0xc9, 0x8d, 0x3c, 0x13, 0xfa, 0x05, 0xfb, + 0x79, 0x61, 0x13, 0xc0, 0xfe, 0x26, 0xe0, 0x1d, 0x70, 0xe5, 0x44, 0xfc, 0x90, 0xc7, 0xd0, 0x0b, + 0x2f, 0x14, 0xca, 0x76, 0xe1, 0x63, 0x30, 0x33, 0xe0, 0x0c, 0x81, 0x77, 0xbb, 0xb1, 0x0a, 0x7d, + 0xcc, 0xab, 0xcb, 0xc7, 0x07, 0x7b, 0x0c, 0x8c, 0x61, 0xfb, 0x1e, 0xbe, 0xdb, 0x8d, 0x38, 0xd2, + 0x25, 0x5d, 0xc3, 0xfe, 0x14, 0x4c, 0x45, 0xd7, 0x03, 0x5c, 0xe9, 0x86, 0x1a, 0x5a, 0xce, 0x50, + 0x56, 0x4b, 0xff, 0x9e, 0x02, 0x49, 0x31, 0x3b, 0x1c, 0x73, 0x02, 0x11, 0x80, 0xb5, 0x26, 0xa5, + 0x44, 0xac, 0xf1, 0xe0, 0x7e, 0xa9, 0x0f, 0xee, 0x57, 0x2f, 0xbc, 0x84, 0xfa, 0xfc, 0x40, 0xbb, + 0x47, 0x0a, 0x65, 0x48, 0xd0, 0x0f, 0x35, 0x85, 0x11, 0xcc, 0xc4, 0x25, 0x30, 0xb5, 0x7b, 0x04, + 0xf3, 0xc7, 0x60, 0x4a, 0x15, 0xcb, 0x15, 0x41, 0xd4, 0x0c, 0x78, 0xae, 0x17, 0x4d, 0xd2, 0x44, + 0x94, 0x56, 0xa6, 0xf2, 0x63, 0x10, 0x37, 0x1f, 0xff, 0x7f, 0xe1, 0xe6, 0xcf, 0xc0, 0x42, 0x50, + 0x9c, 0xb4, 0x69, 0x83, 0x58, 0x66, 0x70, 0x95, 0xc6, 0xfe, 0x99, 0x7d, 0x51, 0xf1, 0x71, 0x5c, + 0x16, 0x1e, 0xaf, 0xfa, 0x45, 0x4c, 0x09, 0x51, 0xd5, 0x08, 0x65, 0x0e, 0xdf, 0x01, 0x86, 0x84, + 0xb7, 0xc8, 0x89, 0xa9, 0x73, 0x51, 0x50, 0x7d, 0x55, 0xc5, 0xd2, 0x19, 0xa1, 0xaf, 0x92, 0x93, + 0x5d, 0xa9, 0xd5, 0x65, 0x58, 0x34, 0x8c, 0x3d, 0x4d, 0x8e, 0xb4, 0x72, 0x07, 0x92, 0x25, 0x02, + 0xae, 0x7b, 0xc4, 0xb1, 0x04, 0x2c, 0xf6, 0xbc, 0xba, 0x5d, 0x93, 0x19, 0x34, 0xe8, 0xae, 0x3e, + 0xbc, 0xfb, 0x97, 0x70, 0x68, 0xeb, 0xf7, 0x0b, 0x2d, 0x68, 0xa0, 0x01, 0x3a, 0xb8, 0x01, 0x72, + 0x3f, 0x6f, 0x92, 0xa6, 0xd8, 0xf9, 0x84, 0x79, 0xae, 0xc3, 0x08, 0x33, 0x52, 0xb2, 0x1c, 0x32, + 0x68, 0xaa, 0xd6, 0xdd, 0x46, 0x03, 0x3b, 0x16, 0xca, 0x2a, 0x1f, 0xe4, 0xbb, 0x08, 0x18, 0x3f, + 0x5a, 0x99, 0x21, 0x18, 0x57, 0x67, 0xfa, 0x0b, 0x60, 0xb4, 0x0f, 0xd2, 0x2e, 0xf0, 0x6f, 0x01, + 0xd4, 0xd1, 0x48, 0xca, 0x8d, 0x6b, 0x35, 0xe2, 0x71, 0x7d, 0xd4, 0xdf, 0x18, 0x94, 0xed, 0xc4, + 0x7e, 0x2a, 0x09, 0x16, 0x5e, 0x96, 0xa6, 0x48, 0x77, 0x26, 0x94, 0x08, 0x2a, 0xe5, 0x47, 0x26, + 0x31, 0x75, 0x78, 0xfa, 0x70, 0xef, 0xbb, 0xbd, 0x08, 0x4f, 0x1d, 0x0e, 0x82, 0xda, 0x31, 0x22, + 0x83, 0xb7, 0x04, 0x33, 0x33, 0x4f, 0x6d, 0xc7, 0x72, 0x4f, 0x99, 0x89, 0x4f, 0xb0, 0x5d, 0xc7, + 0xfb, 0xba, 0xec, 0x97, 0x44, 0x90, 0xb6, 0x9e, 0x2a, 0x55, 0xd9, 0xd7, 0x2c, 0xfc, 0x5b, 0x1c, + 0x80, 0x48, 0x3c, 0x4b, 0x60, 0xd2, 0x53, 0xb4, 0x5f, 0xee, 0xf8, 0xa9, 0x4a, 0xb2, 0xf3, 0x4d, + 0x71, 0xdc, 0x4b, 0xb7, 0x5e, 0x45, 0xbe, 0x02, 0xfe, 0x04, 0x4c, 0xfa, 0x61, 0x26, 0x5e, 0x18, + 0xa6, 0xde, 0xbf, 0xbe, 0x07, 0x7c, 0x67, 0xf4, 0x17, 0x07, 0xe5, 0x29, 0xcd, 0xf5, 0x05, 0xe3, + 0xbf, 0xe7, 0x41, 0x2a, 0xb8, 0x83, 0xc3, 0xf7, 0xa3, 0x77, 0xf5, 0x9b, 0x43, 0xef, 0xea, 0x17, + 0x5c, 0xd2, 0xd7, 0x01, 0xa8, 0x51, 0x82, 0xf5, 0xe3, 0x40, 0xe2, 0x32, 0x8f, 0x03, 0xda, 0xaf, + 0xcc, 0x05, 0x48, 0xd3, 0xb3, 0x7c, 0x90, 0xb1, 0xcb, 0x80, 0x68, 0xbf, 0x32, 0x0f, 0x0a, 0x37, + 0xe3, 0x91, 0x7a, 0xd2, 0x22, 0x48, 0x5b, 0x84, 0xd5, 0xa8, 0xed, 0x89, 0x3d, 0x21, 0xd3, 0x47, + 0x0a, 0x45, 0x45, 0x92, 0x75, 0x71, 0x4e, 0xed, 0xfd, 0x26, 0x27, 0xcc, 0x98, 0x90, 0x2b, 0xfa, + 0xcd, 0xa1, 0x03, 0x51, 0x2a, 0x07, 0xb6, 0x1b, 0x0e, 0xa7, 0x67, 0x28, 0xe2, 0x0c, 0x3f, 0x03, + 0x69, 0x9d, 0x0b, 0x4d, 0x31, 0xa8, 0x93, 0x97, 0x2f, 0x80, 0xc8, 0x62, 0xbe, 0x2f, 0xaf, 0x32, + 0x04, 0x4e, 0x7c, 0x1b, 0x06, 0x2b, 0x00, 0x32, 0x42, 0x65, 0xb2, 0xf6, 0xa8, 0x7b, 0x60, 0xd7, + 0x89, 0x69, 0x5b, 0x32, 0x49, 0xa4, 0xd4, 0x23, 0xc4, 0xae, 0xd2, 0xee, 0x28, 0xe5, 0x66, 0x15, + 0xe5, 0x58, 0xb7, 0xc4, 0x82, 0x77, 0xc1, 0xbc, 0x7e, 0xdf, 0x32, 0x85, 0x8e, 0x50, 0xf9, 0x1e, + 0x46, 0x18, 0x93, 0x84, 0x3e, 0x85, 0x66, 0xb5, 0x76, 0x57, 0x2a, 0xcb, 0x4a, 0x27, 0x88, 0x7d, + 0x34, 0x41, 0xf5, 0x78, 0x02, 0xe9, 0x69, 0x44, 0x2c, 0xba, 0xbd, 0x4b, 0x60, 0x46, 0x6e, 0xcb, + 0x1e, 0xb7, 0xb4, 0x74, 0xcb, 0x0b, 0x55, 0xb7, 0xfd, 0x03, 0x90, 0xaa, 0xbb, 0x0a, 0x88, 0x19, + 0x53, 0x72, 0x3e, 0x96, 0x87, 0xcf, 0xc7, 0x96, 0x6f, 0xaa, 0xa6, 0x23, 0x74, 0x1d, 0x58, 0x28, + 0x99, 0x1e, 0xb9, 0x50, 0x92, 0x19, 0x58, 0x28, 0x19, 0x70, 0xea, 0x65, 0xbf, 0xcf, 0x8a, 0x54, + 0xee, 0xfb, 0xae, 0x48, 0xe5, 0x2f, 0x51, 0x91, 0xea, 0x2b, 0xdf, 0xc0, 0x51, 0xca, 0x37, 0x33, + 0x03, 0xca, 0x37, 0x7d, 0xc5, 0x99, 0xd9, 0x91, 0x8b, 0x33, 0x73, 0x43, 0x8a, 0x33, 0xef, 0x80, + 0x14, 0x75, 0x5d, 0x6e, 0xca, 0xc4, 0x38, 0x2f, 0x77, 0x9e, 0xd1, 0xc7, 0xd8, 0x5c, 0x97, 0x8b, + 0xac, 0x88, 0x92, 0x54, 0xff, 0x82, 0x4f, 0xc0, 0x84, 0x43, 0xb8, 0x18, 0x89, 0xab, 0x32, 0x55, + 0xdf, 0xff, 0x53, 0xbb, 0xb8, 0x76, 0xa9, 0xf7, 0xe0, 0x6d, 0xc2, 0x37, 0xab, 0x9d, 0x76, 0xf1, + 0x8a, 0xfc, 0x81, 0xae, 0x38, 0x84, 0xcb, 0xfa, 0xed, 0x54, 0x57, 0x25, 0xcd, 0x78, 0x71, 0x25, + 0x4d, 0x3e, 0xb0, 0x45, 0x4b, 0x68, 0xe9, 0x46, 0xa4, 0x76, 0xb6, 0x0e, 0x52, 0x12, 0x50, 0x1c, + 0x87, 0xc6, 0x2b, 0x83, 0xfb, 0xe7, 0x1f, 0x97, 0x95, 0xa9, 0x4e, 0xbb, 0x18, 0x90, 0x51, 0x94, + 0x14, 0x38, 0x92, 0x96, 0xde, 0x06, 0x93, 0x4c, 0x1d, 0x0e, 0xc6, 0x82, 0x84, 0xb8, 0x3a, 0xe4, + 0xec, 0x40, 0xbe, 0x1d, 0x7c, 0x1f, 0xf8, 0x47, 0xb8, 0xe9, 0xbb, 0x5e, 0xbb, 0xd8, 0x35, 0xa3, + 0xed, 0xfd, 0x87, 0xf7, 0x9b, 0x20, 0x13, 0x30, 0x2e, 0x39, 0x89, 0xc6, 0x75, 0xc9, 0xb3, 0xa6, + 0x34, 0xcf, 0x92, 0x13, 0x08, 0xdf, 0x00, 0xd9, 0x26, 0x23, 0x56, 0x68, 0xc5, 0x8c, 0x57, 0x17, + 0xc7, 0x96, 0xa7, 0xd1, 0xb4, 0x10, 0xfb, 0x66, 0x4c, 0xd8, 0x49, 0xb4, 0x70, 0x4d, 0x18, 0x85, + 0xf0, 0x8d, 0x3b, 0x58, 0x10, 0xf0, 0x47, 0xda, 0x8e, 0x7e, 0xa1, 0xef, 0x9a, 0xb7, 0x8c, 0xa2, + 0x7c, 0xc7, 0xcc, 0x75, 0xda, 0xc5, 0xa9, 0x2d, 0xcc, 0x38, 0xfa, 0x48, 0xde, 0x23, 0x6f, 0xa9, + 0x40, 0xd0, 0x17, 0xea, 0xab, 0xdf, 0xf1, 0xb6, 0xb1, 0x38, 0xd0, 0xf1, 0x76, 0x97, 0xe3, 0x6d, + 0xf8, 0x39, 0xb8, 0xd6, 0xcb, 0x2c, 0x29, 0xa9, 0x11, 0xfb, 0x44, 0x1d, 0x6a, 0xaf, 0x5d, 0x86, + 0xb9, 0x06, 0xf4, 0x13, 0x69, 0x84, 0x32, 0x87, 0x3f, 0x01, 0x69, 0xf5, 0x72, 0xac, 0xd6, 0xc0, + 0xd2, 0x90, 0xd4, 0x20, 0x4c, 0xd4, 0xbc, 0x03, 0x2f, 0xf8, 0x0d, 0x57, 0x00, 0xdc, 0x97, 0x75, + 0xc6, 0x33, 0xc1, 0x5e, 0x6b, 0xc4, 0xe1, 0xf8, 0x90, 0x18, 0x37, 0x16, 0xe3, 0xcb, 0x09, 0x94, + 0xd7, 0x9a, 0x9d, 0x40, 0x01, 0x7f, 0x00, 0xb2, 0x01, 0xeb, 0xd6, 0xf5, 0x88, 0x9b, 0x8b, 0xf1, + 0xe5, 0x2b, 0x28, 0xe3, 0x8b, 0x75, 0xa1, 0x01, 0x8b, 0x4d, 0x2a, 0xbc, 0x4c, 0x6c, 0x51, 0xfd, + 0x44, 0xc4, 0x8c, 0xd7, 0x65, 0xd6, 0xee, 0xbb, 0x94, 0xa8, 0xd7, 0x22, 0x5d, 0x19, 0x55, 0x67, + 0x16, 0x92, 0xce, 0xe5, 0x2a, 0x52, 0x3a, 0x26, 0x76, 0xb6, 0x94, 0x58, 0x54, 0x4b, 0x60, 0x15, + 0x64, 0x74, 0x13, 0x3e, 0xfc, 0x1b, 0x23, 0xc0, 0xa3, 0x69, 0xe5, 0xe4, 0xa3, 0x7c, 0x04, 0x34, + 0x72, 0xc0, 0xaf, 0x99, 0xf1, 0x03, 0x89, 0x53, 0xec, 0xbb, 0xc1, 0xfa, 0x5d, 0xd4, 0x48, 0x59, + 0xe5, 0xe8, 0x8b, 0x99, 0x20, 0xee, 0x9a, 0xc3, 0x0e, 0xe2, 0xed, 0xcc, 0x58, 0x96, 0xb8, 0xa3, + 0x11, 0x77, 0x05, 0x34, 0x40, 0xc5, 0xe0, 0x87, 0x00, 0x44, 0xea, 0xcc, 0x6f, 0x5e, 0xae, 0xce, + 0x8c, 0x22, 0xbe, 0x10, 0x83, 0x8c, 0x47, 0xdd, 0x13, 0x5b, 0xec, 0x47, 0x42, 0x45, 0xb6, 0x7b, + 0x4b, 0xe6, 0xfd, 0x7b, 0x9d, 0x76, 0x71, 0x7a, 0x27, 0xd4, 0x5c, 0xe6, 0x65, 0x69, 0x3a, 0x82, + 0xb8, 0x69, 0xc1, 0x2a, 0xc8, 0x07, 0x02, 0x91, 0x2c, 0x2c, 0xcc, 0xb1, 0xf1, 0x43, 0x9d, 0x29, + 0x7a, 0xd7, 0xfc, 0xae, 0xfc, 0x5f, 0x25, 0x94, 0x8b, 0x7a, 0x54, 0x31, 0xc7, 0x0b, 0x3f, 0x05, + 0xd9, 0x1e, 0x82, 0x05, 0x73, 0x60, 0xec, 0x98, 0xa8, 0x97, 0xd6, 0x14, 0x12, 0x3f, 0xe1, 0xac, + 0x7f, 0x31, 0x57, 0x0f, 0x87, 0xea, 0xe3, 0x5e, 0xe2, 0xc7, 0xf1, 0x85, 0x27, 0x20, 0xd3, 0xcd, + 0x07, 0x06, 0x78, 0x97, 0xa2, 0xde, 0x03, 0x92, 0xa8, 0x0f, 0x10, 0xc1, 0xd5, 0xcc, 0xf9, 0x43, + 0x00, 0x02, 0xde, 0xc1, 0xe0, 0x3d, 0x90, 0x0e, 0xff, 0xd7, 0x4c, 0x30, 0xe8, 0x31, 0x59, 0x18, + 0x1b, 0x46, 0x54, 0x10, 0x20, 0x81, 0xef, 0xd2, 0x67, 0x60, 0x7e, 0x5d, 0x72, 0xdf, 0x50, 0xad, + 0xa9, 0x7d, 0x05, 0x80, 0x10, 0x35, 0xa8, 0xf4, 0x0f, 0x03, 0x8d, 0x70, 0xf1, 0x54, 0x00, 0xbf, + 0xf4, 0x2f, 0x71, 0x30, 0xff, 0x58, 0xb2, 0xe2, 0xef, 0x03, 0x1e, 0xde, 0x07, 0x20, 0xfc, 0x6f, + 0xb4, 0xa1, 0x84, 0xff, 0x81, 0x30, 0x79, 0x88, 0xd9, 0xb1, 0xbe, 0x82, 0xa4, 0x0e, 0x7c, 0xc1, + 0xd2, 0x7f, 0xc6, 0xc1, 0xcc, 0x07, 0x84, 0xf7, 0x05, 0xb7, 0x07, 0x32, 0x61, 0x70, 0xe6, 0xcb, + 0x5f, 0x4b, 0xa6, 0x48, 0xa8, 0x67, 0xdf, 0x3d, 0xdc, 0xff, 0x8d, 0x83, 0xb9, 0x2d, 0x9b, 0x85, + 0xf1, 0x32, 0x3f, 0xe0, 0x4f, 0x40, 0x36, 0x9a, 0x00, 0xc2, 0x88, 0xdf, 0xb8, 0x60, 0xeb, 0x0f, + 0x8e, 0x39, 0x83, 0xa3, 0x16, 0xdf, 0x3d, 0x6a, 0xb1, 0x49, 0x5c, 0x6a, 0x11, 0xaa, 0x1f, 0x79, + 0xd5, 0x87, 0x7c, 0x43, 0x97, 0xff, 0x08, 0xa4, 0xfe, 0xd1, 0x4c, 0x7d, 0x88, 0x8b, 0x93, 0x27, + 0x8e, 0x03, 0xf5, 0x6f, 0x65, 0xf2, 0xf7, 0xd2, 0xaf, 0xe2, 0x60, 0x66, 0x77, 0xc0, 0x24, 0xfd, + 0x08, 0x4c, 0x8c, 0xba, 0x7a, 0x54, 0x4c, 0xda, 0xfc, 0x3b, 0xf7, 0xe8, 0xad, 0x07, 0x00, 0x84, + 0x87, 0x1b, 0xcc, 0x83, 0xe9, 0x9d, 0x47, 0x4f, 0x37, 0x90, 0xf9, 0x78, 0xfb, 0xe3, 0xed, 0x47, + 0x4f, 0xb7, 0x73, 0xb1, 0x50, 0x54, 0x29, 0xef, 0xed, 0x6d, 0xa0, 0x4f, 0x72, 0x71, 0x08, 0x41, + 0x46, 0x89, 0x36, 0xfe, 0x6e, 0x6f, 0x03, 0x6d, 0x97, 0xb7, 0x72, 0x89, 0xca, 0xbf, 0xc6, 0xbf, + 0x7a, 0x5e, 0x88, 0x7f, 0xfd, 0xbc, 0x10, 0xff, 0xe3, 0xf3, 0x42, 0xec, 0xcf, 0xcf, 0x0b, 0xb1, + 0xbf, 0x3c, 0x2f, 0xc4, 0xfe, 0xfa, 0xbc, 0x10, 0xfb, 0xf6, 0x79, 0x21, 0xfe, 0x8b, 0x4e, 0x21, + 0xfe, 0xcb, 0x4e, 0x21, 0xf6, 0xbb, 0x4e, 0x21, 0xfe, 0xfb, 0x4e, 0x21, 0xf6, 0x65, 0xa7, 0x10, + 0xfb, 0x43, 0xa7, 0x10, 0xfb, 0xaa, 0x53, 0x88, 0x7f, 0xdd, 0x29, 0xc4, 0xff, 0xd8, 0x29, 0xc4, + 0xfe, 0xdc, 0x29, 0xc4, 0xff, 0xd2, 0x29, 0xc4, 0xfe, 0xda, 0x29, 0xc4, 0xbf, 0xed, 0x14, 0x62, + 0xbf, 0x38, 0x2f, 0xc4, 0x7e, 0x79, 0x5e, 0x88, 0xff, 0xfa, 0xbc, 0x10, 0xfb, 0xcd, 0x79, 0x21, + 0xfe, 0xdb, 0xf3, 0x42, 0xec, 0x77, 0xe7, 0x85, 0xd8, 0xef, 0xcf, 0x0b, 0xf1, 0x2f, 0xcf, 0x0b, + 0xf1, 0x3f, 0x9c, 0x17, 0xe2, 0x9f, 0xbe, 0x3d, 0x2a, 0xab, 0xe4, 0x8e, 0xb7, 0xbf, 0x3f, 0x21, + 0x47, 0xe4, 0xce, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x19, 0xc6, 0x35, 0x44, 0xe2, 0x2a, 0x00, + 0x00, } diff --git a/pkg/ttnpb/end_device.validator.pb.go b/pkg/ttnpb/end_device.validator.pb.go index 85d4ed05e1..cc182c85fa 100644 --- a/pkg/ttnpb/end_device.validator.pb.go +++ b/pkg/ttnpb/end_device.validator.pb.go @@ -76,9 +76,9 @@ func (this *EndDeviceVersion) Validate() error { if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(&(this.EndDeviceVersionIdentifiers)); err != nil { return github_com_mwitkow_go_proto_validators.FieldError("EndDeviceVersionIdentifiers", err) } - if this.DefaultMACParameters != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.DefaultMACParameters); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("DefaultMACParameters", err) + if this.DefaultMACSettings != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.DefaultMACSettings); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("DefaultMACSettings", err) } } if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(&(this.DefaultFormatters)); err != nil { @@ -87,6 +87,51 @@ func (this *EndDeviceVersion) Validate() error { return nil } func (this *MACSettings) Validate() error { + if this.ClassBTimeout != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.ClassBTimeout); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("ClassBTimeout", err) + } + } + if this.PingSlotPeriodicity != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.PingSlotPeriodicity); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("PingSlotPeriodicity", err) + } + } + if this.PingSlotDataRateIndex != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.PingSlotDataRateIndex); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("PingSlotDataRateIndex", err) + } + } + if this.ClassCTimeout != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.ClassCTimeout); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("ClassCTimeout", err) + } + } + if this.Rx1Delay != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Rx1Delay); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("Rx1Delay", err) + } + } + if this.Rx1DataRateOffset != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Rx1DataRateOffset); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("Rx1DataRateOffset", err) + } + } + if this.Rx2DataRateIndex != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Rx2DataRateIndex); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("Rx2DataRateIndex", err) + } + } + if this.MaxDutyCycle != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.MaxDutyCycle); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("MaxDutyCycle", err) + } + } + if this.Supports32BitFCnt != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Supports32BitFCnt); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("Supports32BitFCnt", err) + } + } if this.UseADR != nil { if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.UseADR); err != nil { return github_com_mwitkow_go_proto_validators.FieldError("UseADR", err) @@ -97,14 +142,9 @@ func (this *MACSettings) Validate() error { return github_com_mwitkow_go_proto_validators.FieldError("ADRMargin", err) } } - if this.ClassBTimeout != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.ClassBTimeout); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("ClassBTimeout", err) - } - } - if this.ClassCTimeout != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.ClassCTimeout); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("ClassCTimeout", err) + if this.ResetsFCnt != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.ResetsFCnt); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("ResetsFCnt", err) } } if this.StatusTimePeriodicity != nil { @@ -117,27 +157,33 @@ func (this *MACSettings) Validate() error { return github_com_mwitkow_go_proto_validators.FieldError("StatusCountPeriodicity", err) } } - if this.Rx1Delay != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Rx1Delay); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("Rx1Delay", err) + if this.DesiredRx1Delay != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.DesiredRx1Delay); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("DesiredRx1Delay", err) } } - if this.Rx2DataRateIndex != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Rx2DataRateIndex); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("Rx2DataRateIndex", err) + if this.DesiredRx1DataRateOffset != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.DesiredRx1DataRateOffset); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("DesiredRx1DataRateOffset", err) } } - if this.Rx2Frequency != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Rx2Frequency); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("Rx2Frequency", err) + if this.DesiredRx2DataRateIndex != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.DesiredRx2DataRateIndex); err != nil { + return github_com_mwitkow_go_proto_validators.FieldError("DesiredRx2DataRateIndex", err) } } return nil } -func (this *MACSettings_RxDelayValue) Validate() error { +func (this *MACSettings_DataRateIndexValue) Validate() error { return nil } -func (this *MACSettings_DataRateIndexValue) Validate() error { +func (this *MACSettings_PingSlotPeriodValue) Validate() error { + return nil +} +func (this *MACSettings_AggregatedDutyCycleValue) Validate() error { + return nil +} +func (this *MACSettings_RxDelayValue) Validate() error { return nil } func (this *MACState) Validate() error { @@ -218,11 +264,6 @@ func (this *EndDevice) Validate() error { } } // Validation of proto3 map<> fields is unsupported. - if this.DefaultMACParameters != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.DefaultMACParameters); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("DefaultMACParameters", err) - } - } if this.RootKeys != nil { if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.RootKeys); err != nil { return github_com_mwitkow_go_proto_validators.FieldError("RootKeys", err) diff --git a/pkg/ttnpb/end_device_populate.go b/pkg/ttnpb/end_device_populate.go index fc5cf7eb1b..340427e284 100644 --- a/pkg/ttnpb/end_device_populate.go +++ b/pkg/ttnpb/end_device_populate.go @@ -29,12 +29,11 @@ func NewPopulatedEndDeviceVersion(r randyEndDevice, easy bool) *EndDeviceVersion if r.Intn(10) != 0 { out.DefaultFormatters = *NewPopulatedMessagePayloadFormatters(r, easy) } - out.DefaultMACParameters = NewPopulatedMACParameters(r, easy) out.MaxFrequency = uint64(r.Uint32()) out.MinFrequency = uint64(r.Uint32()) % out.MaxFrequency out.ResetsFCnt = bool(r.Intn(2) == 0) - out.Uses32BitFCnt = bool(r.Intn(2) == 0) out.ResetsJoinNonces = bool(r.Intn(2) == 0) + out.DefaultMACSettings = NewPopulatedMACSettings(r, easy) return out } From d210908bf7014c3adb07eb9c5d01b54d36af6f33 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 13 Feb 2019 13:26:38 +0100 Subject: [PATCH 17/40] ns: Fix handling of joined devices --- pkg/networkserver/downlink.go | 2 +- pkg/networkserver/errors.go | 4 +- pkg/networkserver/grpc_deviceregistry.go | 218 +++++++++++++++++++---- pkg/networkserver/grpc_gsns.go | 13 +- pkg/networkserver/redis/registry.go | 26 +-- 5 files changed, 211 insertions(+), 52 deletions(-) diff --git a/pkg/networkserver/downlink.go b/pkg/networkserver/downlink.go index 7ae85d449c..24da95dd95 100644 --- a/pkg/networkserver/downlink.go +++ b/pkg/networkserver/downlink.go @@ -178,7 +178,7 @@ outer: pld := &ttnpb.MACPayload{ FHDR: ttnpb.FHDR{ - DevAddr: *dev.EndDeviceIdentifiers.DevAddr, + DevAddr: dev.Session.DevAddr, FCtrl: ttnpb.FCtrl{ Ack: up != nil && up.Payload.MHDR.MType == ttnpb.MType_CONFIRMED_UP, }, diff --git a/pkg/networkserver/errors.go b/pkg/networkserver/errors.go index 52521affc7..a134b359a7 100644 --- a/pkg/networkserver/errors.go +++ b/pkg/networkserver/errors.go @@ -35,13 +35,11 @@ var ( errEncryptMAC = errors.DefineInternal("encrypt_mac", "failed to encrypt MAC commands") errFCntTooHigh = errors.DefineInvalidArgument("f_cnt_too_high", "FCnt is too high") errGatewayServerNotFound = errors.DefineNotFound("gateway_server_not_found", "Gateway Server not found") - errInvalidADRMargin = errors.DefineInvalidArgument("adr_margin", "invalid ADR margin") errInvalidChannelIndex = errors.DefineInvalidArgument("channel_index", "invalid channel index") - errInvalidClassBTimeout = errors.DefineInvalidArgument("class_b_timeout", "invalid class B timeout") - errInvalidClassCTimeout = errors.DefineInvalidArgument("class_c_timeout", "invalid class C timeout") errInvalidConfiguration = errors.DefineInvalidArgument("configuration", "invalid configuration") errInvalidDataRate = errors.DefineInvalidArgument("data_rate", "invalid data rate") errInvalidFieldMask = errors.DefineInvalidArgument("field_mask", "invalid field mask") + errInvalidFieldValue = errors.DefineInvalidArgument("field_value", "invalid value of field `{field}`") errInvalidFNwkSIntKey = errors.DefineInvalidArgument("invalid_f_nwk_s_int_key", "invalid FNwkSIntKey") errInvalidNwkSEncKey = errors.DefineInvalidArgument("invalid_nwk_s_enc_key", "invalid NwkSEncKey") errInvalidPayload = errors.DefineInvalidArgument("payload", "invalid payload") diff --git a/pkg/networkserver/grpc_deviceregistry.go b/pkg/networkserver/grpc_deviceregistry.go index dcd04c21b4..16953d978b 100644 --- a/pkg/networkserver/grpc_deviceregistry.go +++ b/pkg/networkserver/grpc_deviceregistry.go @@ -45,20 +45,165 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest if err := rights.RequireApplication(ctx, req.Device.ApplicationIdentifiers, ttnpb.RIGHT_APPLICATION_DEVICES_WRITE); err != nil { return nil, err } + + gets := append(req.FieldMask.Paths[:0:0], req.FieldMask.Paths...) + if ttnpb.HasAnyField(req.FieldMask.Paths, "queued_application_downlinks") { + gets = append(gets, + "mac_state.device_class", + ) + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_state.device_class") { + gets = append(gets, + "mac_state.current_parameters", + "mac_state.desired_parameters", + "queued_application_downlinks", + ) + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_state.desired_parameters") { + gets = append(gets, + "mac_state.current_parameters", + "mac_state.device_class", + ) + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_state.current_parameters") { + gets = append(gets, + "mac_state.desired_parameters", + "mac_state.device_class", + ) + } + var addDownlinkTask bool - dev, err := ns.devices.SetByID(ctx, req.Device.EndDeviceIdentifiers.ApplicationIdentifiers, req.Device.EndDeviceIdentifiers.DeviceID, req.FieldMask.Paths, func(dev *ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error) { - paths := req.FieldMask.Paths + dev, err := ns.devices.SetByID(ctx, req.Device.EndDeviceIdentifiers.ApplicationIdentifiers, req.Device.EndDeviceIdentifiers.DeviceID, gets, func(dev *ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error) { + if err := ttnpb.ProhibitFields(req.FieldMask.Paths, + "mac_state", + "pending_session", + ); err != nil { + return nil, nil, errInvalidFieldMask.WithCause(err) + } + if dev != nil { - addDownlinkTask = ttnpb.HasAnyField(paths, "mac_state.device_class") && req.Device.MACState.DeviceClass != ttnpb.CLASS_A || - ttnpb.HasAnyField(paths, "queued_application_downlinks") && len(req.Device.QueuedApplicationDownlinks) > 0 - return &req.Device, paths, nil + if err := ttnpb.ProhibitFields(req.FieldMask.Paths, + "session", + ); err != nil { + return nil, nil, errInvalidFieldMask.WithCause(err) + } + + addDownlinkTask = ttnpb.HasAnyField(req.FieldMask.Paths, + "mac_state.current_parameters", + "mac_state.desired_parameters", + "mac_state.device_class", + "queued_application_downlinks", + ) && req.Device.MACState.DeviceClass != ttnpb.CLASS_A && + (len(req.Device.QueuedApplicationDownlinks) > 0 || !req.Device.MACState.CurrentParameters.Equal(req.Device.MACState.DesiredParameters)) + return &req.Device, req.FieldMask.Paths, nil } - if ttnpb.HasAnyField(paths, "version_ids") { + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.dev_addr") && req.Device.Session == nil || req.Device.Session.DevAddr.IsZero() { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.dev_addr") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.session_key_id") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetSessionKeyID()) == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.session_key_id") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.f_nwk_s_int_key.key") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetFNwkSIntKey().GetKey()) == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.f_nwk_s_int_key.key") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.f_nwk_s_int_key.kek_label") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetFNwkSIntKey().GetKEKLabel()) == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.f_nwk_s_int_key.kek_label") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.s_nwk_s_int_key.key") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetSNwkSIntKey().GetKey()) == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.s_nwk_s_int_key.key") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.s_nwk_s_int_key.kek_label") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetSNwkSIntKey().GetKEKLabel()) == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.s_nwk_s_int_key.kek_label") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.nwk_s_enc_key.key") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetNwkSEncKey().GetKey()) == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.nwk_s_enc_key.key") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.nwk_s_enc_key.kek_label") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetNwkSEncKey().GetKEKLabel()) == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.nwk_s_enc_key.kek_label") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.app_s_key.key") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetAppSKey().GetKey()) == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.app_s_key.key") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.app_s_key.kek_label") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetAppSKey().GetKEKLabel()) == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.app_s_key.kek_label") + } + + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.class_b_timeout") && req.Device.GetMACSettings().GetClassBTimeout() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.class_b_timeout") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.ping_slot_periodicity") && req.Device.GetMACSettings().GetPingSlotPeriodicity() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.ping_slot_periodicity") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.ping_slot_date_rate_index") && req.Device.GetMACSettings().GetPingSlotDataRateIndex() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.ping_slot_date_rate_index") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.ping_slot_frequency") && req.Device.GetMACSettings().GetPingSlotFrequency() == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.ping_slot_frequency") + } + + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.class_c_timeout") && req.Device.GetMACSettings().GetClassCTimeout() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.class_c_timeout") + } + + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.rx1_delay") && req.Device.GetMACSettings().GetRx1Delay() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.rx1_delay") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.rx1_data_rate_offset") && req.Device.GetMACSettings().GetRx1DataRateOffset() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.rx1_data_rate_offset") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.rx2_data_rate_index") && req.Device.GetMACSettings().GetRx2DataRateIndex() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.rx2_data_rate_index") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.rx2_frequency") && req.Device.GetMACSettings().GetRx2Frequency() == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.rx2_frequency") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.factory_preset_frequencies") && len(req.Device.GetMACSettings().GetFactoryPresetFrequencies()) == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.factory_preset_frequencies") + } + + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.max_duty_cycle") && req.Device.GetMACSettings().GetMaxDutyCycle() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.max_duty_cycle") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.supports_32_bit_f_cnt") && req.Device.GetMACSettings().GetSupports32BitFCnt() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.supports_32_bit_f_cnt") + } + + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.use_adr") && req.Device.GetMACSettings().GetUseADR() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.use_adr") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.adr_margin") && req.Device.GetMACSettings().GetADRMargin() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.adr_margin") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.resets_f_cnt") && req.Device.GetMACSettings().GetResetsFCnt() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.resets_f_cnt") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.status_time_periodicity") && req.Device.GetMACSettings().GetStatusTimePeriodicity() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.status_time_periodicity") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.status_count_periodicity") && req.Device.GetMACSettings().GetStatusCountPeriodicity() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.status_count_periodicity") + } + + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.desired_rx1_delay") && req.Device.GetMACSettings().GetDesiredRx1Delay() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.desired_rx1_delay") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.desired_rx1_data_rate_offset") && req.Device.GetMACSettings().GetDesiredRx1DataRateOffset() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.desired_rx1_data_rate_offset") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.desired_rx2_data_rate_index") && req.Device.GetMACSettings().GetDesiredRx2DataRateIndex() == nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.desired_rx2_data_rate_index") + } + if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.desired_rx2_frequency") && req.Device.GetMACSettings().GetDesiredRx2Frequency() == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.desired_rx2_frequency") + } + + sets := append(req.FieldMask.Paths[:0:0], req.FieldMask.Paths...) + if ttnpb.HasAnyField(sets, "version_ids") { // TODO: Apply version IDs (https://github.com/TheThingsIndustries/lorawan-stack/issues/1544) } - if err := ttnpb.RequireFields(paths, + if err := ttnpb.RequireFields(sets, "frequency_plan_id", "lorawan_phy_version", "lorawan_version", @@ -66,42 +211,44 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest ); err != nil { return nil, nil, errInvalidFieldMask.WithCause(err) } - - if ttnpb.HasAnyField(paths, "mac_settings.adr_margin") && req.Device.GetMACSettings().GetADRMargin() == nil { - return nil, nil, errInvalidADRMargin + if len(req.Device.FrequencyPlanID) == 0 { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "frequency_plan_id") } - if ttnpb.HasAnyField(paths, "mac_settings.class_b_timeout") && req.Device.GetMACSettings().GetClassBTimeout() == nil { - return nil, nil, errInvalidClassBTimeout + if err := req.Device.LoRaWANVersion.Validate(); err != nil { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "lorawan_version").WithCause(err) } - if ttnpb.HasAnyField(paths, "mac_settings.class_c_timeout") && req.Device.GetMACSettings().GetClassCTimeout() == nil { - return nil, nil, errInvalidClassCTimeout + if req.Device.LoRaWANPHYVersion == ttnpb.PHY_UNKNOWN { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "lorawan_phy_version") } - if !ttnpb.HasAnyField(paths, "uses_32_bit_f_cnt") { - dev.Uses32BitFCnt = true - paths = append(paths, "uses_32_bit_f_cnt") + if ttnpb.HasAnyField(sets, "supports_class_b") && req.Device.SupportsClassB { + if err := ttnpb.RequireFields(sets, + "mac_settings.ping_slot_date_rate_index", + "mac_settings.ping_slot_frequency", + "mac_settings.ping_slot_periodicity", + ); err != nil { + return nil, nil, errInvalidFieldMask.WithCause(err) + } } - if req.Device.SupportsJoin { - return &req.Device, paths, nil + if req.Device.SupportsJoin && !ttnpb.HasAnyField(sets, "session") { + return &req.Device, sets, nil } - if err := ttnpb.RequireFields(paths, + if err := ttnpb.RequireFields(sets, "session.dev_addr", "session.keys.f_nwk_s_int_key.key", ); err != nil { return nil, nil, errInvalidFieldMask.WithCause(err) } - if req.Device.Session == nil { - return nil, nil, errEmptySession - } + req.Device.EndDeviceIdentifiers.DevAddr = &req.Device.Session.DevAddr if !validABPSessionKey(req.Device.Session.FNwkSIntKey) { return nil, nil, errInvalidFNwkSIntKey } if req.Device.LoRaWANVersion.Compare(ttnpb.MAC_V1_1) >= 0 { - if err := ttnpb.RequireFields(paths, + if err := ttnpb.RequireFields(sets, "session.keys.nwk_s_enc_key.key", "session.keys.s_nwk_s_int_key.key", ); err != nil { @@ -116,7 +263,7 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest return nil, nil, errInvalidNwkSEncKey } } else { - if err := ttnpb.ProhibitFields(paths, + if err := ttnpb.ProhibitFields(sets, "session.keys.nwk_s_enc_key.key", "session.keys.s_nwk_s_int_key.key", ); err != nil { @@ -125,21 +272,24 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest // TODO: Encrypt (https://github.com/TheThingsIndustries/lorawan-stack/issues/1562) req.Device.Session.SNwkSIntKey = req.Device.Session.FNwkSIntKey req.Device.Session.NwkSEncKey = req.Device.Session.FNwkSIntKey - paths = append(paths, "session.keys.s_nwk_s_int_key", "session.keys.nwk_s_enc_key") + sets = append(sets, "session.keys.s_nwk_s_int_key", "session.keys.nwk_s_enc_key") + } + + if ttnpb.HasAnyField(sets, "session.started_at") && req.Device.GetSession().GetStartedAt().IsZero() { + return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.started_at") + } else if !ttnpb.HasAnyField(sets, "session.started_at") { + req.Device.Session.StartedAt = time.Now().UTC() + sets = append(sets, "session.started_at") } - req.Device.Session.StartedAt = time.Now().UTC() - paths = append(paths, "session.started_at") if err := resetMACState(&req.Device, ns.FrequencyPlans, ns.defaultMACSettings); err != nil { return nil, nil, err } - if req.Device.MACState.DeviceClass != ttnpb.CLASS_A { - addDownlinkTask = len(req.Device.QueuedApplicationDownlinks) > 0 || - !req.Device.MACState.CurrentParameters.Equal(req.Device.MACState.DesiredParameters) - } - paths = append(paths, "mac_state") - return &req.Device, paths, nil + addDownlinkTask = req.Device.MACState.DeviceClass != ttnpb.CLASS_A && + (len(req.Device.QueuedApplicationDownlinks) > 0 || !req.Device.MACState.CurrentParameters.Equal(req.Device.MACState.DesiredParameters)) + + return &req.Device, sets, nil }) if err != nil { return nil, err diff --git a/pkg/networkserver/grpc_gsns.go b/pkg/networkserver/grpc_gsns.go index 403df98b7f..791bcd4dfd 100644 --- a/pkg/networkserver/grpc_gsns.go +++ b/pkg/networkserver/grpc_gsns.go @@ -161,6 +161,7 @@ func (ns *NetworkServer) matchDevice(ctx context.Context, up *ttnpb.UplinkMessag } } } + devs = append(devs, device{ EndDevice: dev, matchedSession: dev.PendingSession, @@ -365,8 +366,14 @@ func (ns *NetworkServer) handleUplink(ctx context.Context, up *ttnpb.UplinkMessa if matched.MACState != nil && matched.MACState.PendingApplicationDownlink != nil { asUp := &ttnpb.ApplicationUp{ - EndDeviceIdentifiers: matched.EndDeviceIdentifiers, - CorrelationIDs: matched.MACState.PendingApplicationDownlink.CorrelationIDs, + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DevAddr: &pld.DevAddr, + JoinEUI: matched.JoinEUI, + DevEUI: matched.DevEUI, + ApplicationIdentifiers: matched.ApplicationIdentifiers, + DeviceID: matched.DeviceID, + }, + CorrelationIDs: matched.MACState.PendingApplicationDownlink.CorrelationIDs, } if pld.Ack { @@ -410,7 +417,7 @@ func (ns *NetworkServer) handleUplink(ctx context.Context, up *ttnpb.UplinkMessa } copy(key[:], ses.NwkSEncKey.Key[:]) - mac, err = crypto.DecryptUplink(key, *matched.EndDeviceIdentifiers.DevAddr, pld.FCnt, mac) + mac, err = crypto.DecryptUplink(key, pld.DevAddr, pld.FCnt, mac) if err != nil { return errDecrypt.WithCause(err) } diff --git a/pkg/networkserver/redis/registry.go b/pkg/networkserver/redis/registry.go index c8170ecbcd..4b5e4988d5 100644 --- a/pkg/networkserver/redis/registry.go +++ b/pkg/networkserver/redis/registry.go @@ -95,7 +95,7 @@ func (r *DeviceRegistry) RangeByAddr(addr types.DevAddr, paths []string, f func( }) } -func getDevAddrsAndIDs(pb *ttnpb.EndDevice) (addrs struct{ current, fallback *types.DevAddr }, ids ttnpb.EndDeviceIdentifiers) { +func getDevAddrsAndIDs(pb *ttnpb.EndDevice) (addrs struct{ current, pending *types.DevAddr }, ids ttnpb.EndDeviceIdentifiers) { if pb == nil { return } @@ -108,7 +108,7 @@ func getDevAddrsAndIDs(pb *ttnpb.EndDevice) (addrs struct{ current, fallback *ty if pb.PendingSession != nil { var addr types.DevAddr copy(addr[:], pb.PendingSession.DevAddr[:]) - addrs.fallback = &addr + addrs.pending = &addr } return addrs, *pb.EndDeviceIdentifiers.Copy(&ttnpb.EndDeviceIdentifiers{}) } @@ -177,8 +177,8 @@ func (r *DeviceRegistry) SetByID(ctx context.Context, appID ttnpb.ApplicationIde if oldIDs.JoinEUI != nil && oldIDs.DevEUI != nil { p.Del(r.Redis.Key(euiKey, oldIDs.JoinEUI.String(), oldIDs.DevEUI.String())) } - if oldAddrs.fallback != nil { - p.SRem(r.Redis.Key(addrKey, oldAddrs.fallback.String()), uid) + if oldAddrs.pending != nil { + p.SRem(r.Redis.Key(addrKey, oldAddrs.pending.String()), uid) } if oldAddrs.current != nil { p.SRem(r.Redis.Key(addrKey, oldAddrs.current.String()), uid) @@ -215,7 +215,11 @@ func (r *DeviceRegistry) SetByID(ctx context.Context, appID ttnpb.ApplicationIde } f = func(p redis.Pipeliner) error { - if create && newIDs.JoinEUI != nil && newIDs.DevEUI != nil { + if create { + if newIDs.JoinEUI == nil || newIDs.DevEUI == nil { + return errInvalidIdentifiers + } + ek := r.Redis.Key(euiKey, newIDs.JoinEUI.String(), newIDs.DevEUI.String()) if err := tx.Watch(ek).Err(); err != nil { return err @@ -236,16 +240,16 @@ func (r *DeviceRegistry) SetByID(ctx context.Context, appID ttnpb.ApplicationIde return err } - if oldAddrs.fallback != nil && !equalAddr(oldAddrs.fallback, newAddrs.fallback) && !equalAddr(oldAddrs.fallback, newAddrs.current) { - p.SRem(r.Redis.Key(addrKey, oldAddrs.fallback.String()), uid) + if oldAddrs.pending != nil && !equalAddr(oldAddrs.pending, newAddrs.pending) && !equalAddr(oldAddrs.pending, newAddrs.current) { + p.SRem(r.Redis.Key(addrKey, oldAddrs.pending.String()), uid) } - if oldAddrs.current != nil && !equalAddr(oldAddrs.current, newAddrs.fallback) && !equalAddr(oldAddrs.current, newAddrs.current) { + if oldAddrs.current != nil && !equalAddr(oldAddrs.current, newAddrs.pending) && !equalAddr(oldAddrs.current, newAddrs.current) { p.SRem(r.Redis.Key(addrKey, oldAddrs.current.String()), uid) } - if newAddrs.fallback != nil && !equalAddr(newAddrs.fallback, oldAddrs.fallback) && !equalAddr(newAddrs.fallback, oldAddrs.current) { - p.SAdd(r.Redis.Key(addrKey, newAddrs.fallback.String()), uid) + if newAddrs.pending != nil && !equalAddr(newAddrs.pending, oldAddrs.pending) && !equalAddr(newAddrs.pending, oldAddrs.current) { + p.SAdd(r.Redis.Key(addrKey, newAddrs.pending.String()), uid) } - if newAddrs.current != nil && !equalAddr(newAddrs.current, oldAddrs.fallback) && !equalAddr(newAddrs.current, oldAddrs.current) { + if newAddrs.current != nil && !equalAddr(newAddrs.current, oldAddrs.pending) && !equalAddr(newAddrs.current, oldAddrs.current) { p.SAdd(r.Redis.Key(addrKey, newAddrs.current.String()), uid) } return nil From 3781e78052c6665f223d546558282c6f33353696 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 15 Feb 2019 12:36:40 +0100 Subject: [PATCH 18/40] ns: Construct valid MAC state on reset --- pkg/networkserver/utils.go | 225 +++++++++++++++++++++++++------------ 1 file changed, 152 insertions(+), 73 deletions(-) diff --git a/pkg/networkserver/utils.go b/pkg/networkserver/utils.go index ad47d9fe01..c001f53ed1 100644 --- a/pkg/networkserver/utils.go +++ b/pkg/networkserver/utils.go @@ -15,9 +15,6 @@ package networkserver import ( - "math" - - "github.com/mohae/deepcopy" "go.thethings.network/lorawan-stack/pkg/band" "go.thethings.network/lorawan-stack/pkg/frequencyplans" "go.thethings.network/lorawan-stack/pkg/ttnpb" @@ -68,28 +65,135 @@ func resetMACState(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults ttn } dev.MACState = &ttnpb.MACState{ - DeviceClass: ttnpb.CLASS_A, LoRaWANVersion: dev.LoRaWANVersion, - CurrentParameters: ttnpb.MACParameters{ - ADRAckDelay: uint32(band.ADRAckDelay), - ADRAckLimit: uint32(band.ADRAckLimit), - ADRNbTrans: 1, - MaxDutyCycle: ttnpb.DUTY_CYCLE_1, - MaxEIRP: band.DefaultMaxEIRP, - Rx1Delay: ttnpb.RxDelay(band.ReceiveDelay1.Seconds()), - Rx2DataRateIndex: band.DefaultRx2Parameters.DataRateIndex, - Rx2Frequency: band.DefaultRx2Parameters.Frequency, - }, - } - if dev.SupportsClassB { - dev.MACState.DeviceClass = ttnpb.CLASS_B } if dev.SupportsClassC { dev.MACState.DeviceClass = ttnpb.CLASS_C + } else if dev.SupportsClassB { + dev.MACState.DeviceClass = ttnpb.CLASS_B + } else { + dev.MACState.DeviceClass = ttnpb.CLASS_A + } + + dev.MACState.CurrentParameters.MaxEIRP = band.DefaultMaxEIRP + dev.MACState.DesiredParameters.MaxEIRP = dev.MACState.CurrentParameters.MaxEIRP + if fp.MaxEIRP != nil && *fp.MaxEIRP > 0 && *fp.MaxEIRP < dev.MACState.CurrentParameters.MaxEIRP { + dev.MACState.DesiredParameters.MaxEIRP = *fp.MaxEIRP + } + + dev.MACState.CurrentParameters.UplinkDwellTime = false + dev.MACState.DesiredParameters.UplinkDwellTime = fp.DwellTime.GetUplinks() + + dev.MACState.CurrentParameters.DownlinkDwellTime = false + dev.MACState.DesiredParameters.DownlinkDwellTime = fp.DwellTime.GetDownlinks() + + dev.MACState.CurrentParameters.ADRDataRateIndex = ttnpb.DATA_RATE_0 + dev.MACState.DesiredParameters.ADRDataRateIndex = dev.MACState.CurrentParameters.ADRDataRateIndex + + dev.MACState.CurrentParameters.ADRTxPowerIndex = 0 + dev.MACState.DesiredParameters.ADRTxPowerIndex = dev.MACState.CurrentParameters.ADRTxPowerIndex + + dev.MACState.CurrentParameters.ADRNbTrans = 1 + dev.MACState.DesiredParameters.ADRNbTrans = dev.MACState.CurrentParameters.ADRNbTrans + + dev.MACState.CurrentParameters.ADRAckLimit = uint32(band.ADRAckLimit) + dev.MACState.DesiredParameters.ADRAckLimit = dev.MACState.CurrentParameters.ADRAckLimit + + dev.MACState.CurrentParameters.ADRAckDelay = uint32(band.ADRAckDelay) + dev.MACState.DesiredParameters.ADRAckDelay = dev.MACState.CurrentParameters.ADRAckDelay + + dev.MACState.CurrentParameters.Rx1Delay = ttnpb.RxDelay(band.ReceiveDelay1.Seconds()) + if dev.GetMACSettings().GetRx1Delay() != nil { + dev.MACState.CurrentParameters.Rx1Delay = dev.MACSettings.Rx1Delay.Value + } else if defaults.Rx1Delay != nil { + dev.MACState.CurrentParameters.Rx1Delay = defaults.Rx1Delay.Value + } + dev.MACState.DesiredParameters.Rx1Delay = dev.MACState.CurrentParameters.Rx1Delay + if dev.GetMACSettings().GetDesiredRx1Delay() != nil { + dev.MACState.DesiredParameters.Rx1Delay = dev.MACSettings.Rx1Delay.Value + } else if defaults.DesiredRx1Delay != nil { + dev.MACState.DesiredParameters.Rx1Delay = defaults.Rx1Delay.Value + } + + dev.MACState.CurrentParameters.Rx1DataRateOffset = 0 + if dev.GetMACSettings().GetRx1DataRateOffset() != nil { + dev.MACState.CurrentParameters.Rx1DataRateOffset = dev.MACSettings.Rx1DataRateOffset.Value + } else if defaults.Rx1DataRateOffset != nil { + dev.MACState.CurrentParameters.Rx1DataRateOffset = defaults.Rx1DataRateOffset.Value + } + dev.MACState.DesiredParameters.Rx1DataRateOffset = dev.MACState.CurrentParameters.Rx1DataRateOffset + if dev.GetMACSettings().GetDesiredRx1DataRateOffset() != nil { + dev.MACState.DesiredParameters.Rx1DataRateOffset = dev.MACSettings.DesiredRx1DataRateOffset.Value + } else if defaults.DesiredRx1DataRateOffset != nil { + dev.MACState.DesiredParameters.Rx1DataRateOffset = defaults.DesiredRx1DataRateOffset.Value + } + + dev.MACState.CurrentParameters.Rx2DataRateIndex = band.DefaultRx2Parameters.DataRateIndex + if dev.GetMACSettings().GetRx2DataRateIndex() != nil { + dev.MACState.CurrentParameters.Rx2DataRateIndex = dev.MACSettings.Rx2DataRateIndex.Value + } else if defaults.Rx2DataRateIndex != nil { + dev.MACState.CurrentParameters.Rx2DataRateIndex = defaults.Rx2DataRateIndex.Value + } + dev.MACState.DesiredParameters.Rx2DataRateIndex = dev.MACState.CurrentParameters.Rx2DataRateIndex + if dev.GetMACSettings().GetDesiredRx2DataRateIndex() != nil { + dev.MACState.DesiredParameters.Rx2DataRateIndex = dev.MACSettings.DesiredRx2DataRateIndex.Value + } else if defaults.DesiredRx2DataRateIndex != nil { + dev.MACState.DesiredParameters.Rx2DataRateIndex = defaults.DesiredRx2DataRateIndex.Value + } else if fp.DefaultRx2DataRate != nil { + dev.MACState.DesiredParameters.Rx2DataRateIndex = ttnpb.DataRateIndex(*fp.DefaultRx2DataRate) + } + + dev.MACState.CurrentParameters.Rx2Frequency = band.DefaultRx2Parameters.Frequency + if dev.GetMACSettings().GetRx2Frequency() != 0 { + dev.MACState.CurrentParameters.Rx2Frequency = dev.MACSettings.Rx2Frequency + } else if defaults.Rx2Frequency != 0 { + dev.MACState.CurrentParameters.Rx2Frequency = defaults.Rx2Frequency + } + dev.MACState.DesiredParameters.Rx2Frequency = dev.MACState.CurrentParameters.Rx2Frequency + if dev.MACSettings != nil && dev.GetMACSettings().GetDesiredRx2Frequency() != 0 { + dev.MACState.DesiredParameters.Rx2Frequency = dev.MACSettings.DesiredRx2Frequency + } else if defaults.DesiredRx2Frequency != 0 { + dev.MACState.DesiredParameters.Rx2Frequency = defaults.DesiredRx2Frequency + } else if fp.Rx2Channel != nil { + dev.MACState.DesiredParameters.Rx2Frequency = fp.Rx2Channel.Frequency + } + + dev.MACState.CurrentParameters.MaxDutyCycle = ttnpb.DUTY_CYCLE_1 + if dev.GetMACSettings().GetMaxDutyCycle() != nil { + dev.MACState.CurrentParameters.MaxDutyCycle = dev.MACSettings.MaxDutyCycle.Value + } + dev.MACState.DesiredParameters.MaxDutyCycle = dev.MACState.CurrentParameters.MaxDutyCycle + + dev.MACState.CurrentParameters.RejoinTimePeriodicity = ttnpb.REJOIN_TIME_0 + dev.MACState.DesiredParameters.RejoinTimePeriodicity = dev.MACState.CurrentParameters.RejoinTimePeriodicity + + dev.MACState.CurrentParameters.RejoinCountPeriodicity = ttnpb.REJOIN_COUNT_16 + dev.MACState.DesiredParameters.RejoinCountPeriodicity = dev.MACState.CurrentParameters.RejoinCountPeriodicity + + dev.MACState.CurrentParameters.PingSlotFrequency = 0 + if dev.GetMACSettings().GetPingSlotFrequency() != 0 { + dev.MACState.CurrentParameters.PingSlotFrequency = dev.MACSettings.PingSlotFrequency + } else if defaults.PingSlotFrequency != 0 { + dev.MACState.CurrentParameters.PingSlotFrequency = defaults.PingSlotFrequency + } + dev.MACState.DesiredParameters.PingSlotFrequency = dev.MACState.CurrentParameters.PingSlotFrequency + if fp.PingSlot != nil && fp.PingSlot.Frequency != 0 { + dev.MACState.DesiredParameters.PingSlotFrequency = fp.PingSlot.Frequency + } + + dev.MACState.CurrentParameters.PingSlotDataRateIndex = ttnpb.DATA_RATE_0 + if dev.GetMACSettings().GetPingSlotDataRateIndex() != nil { + dev.MACState.CurrentParameters.PingSlotDataRateIndex = dev.MACSettings.PingSlotDataRateIndex.Value + } else if defaults.PingSlotDataRateIndex != nil { + dev.MACState.CurrentParameters.PingSlotDataRateIndex = defaults.PingSlotDataRateIndex.Value + } + dev.MACState.DesiredParameters.PingSlotDataRateIndex = dev.MACState.CurrentParameters.PingSlotDataRateIndex + if fp.DefaultPingSlotDataRate != nil { + dev.MACState.DesiredParameters.PingSlotDataRateIndex = ttnpb.DataRateIndex(*fp.DefaultPingSlotDataRate) } - // NOTE: dev.MACState.CurrentParameters must not contain pointer values at this point. - dev.MACState.DesiredParameters = dev.MACState.CurrentParameters + dev.MACState.CurrentParameters.BeaconFrequency = 0 + dev.MACState.DesiredParameters.BeaconFrequency = dev.MACState.CurrentParameters.BeaconFrequency if len(band.DownlinkChannels) > len(band.UplinkChannels) || len(fp.DownlinkChannels) > len(fp.UplinkChannels) || len(band.UplinkChannels) > int(band.MaxUplinkChannels) || len(band.DownlinkChannels) > int(band.MaxDownlinkChannels) || @@ -99,28 +203,42 @@ func resetMACState(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults ttn panic("uplink/downlink channel length is inconsistent") } - dev.MACState.CurrentParameters.Channels = make([]*ttnpb.MACParameters_Channel, len(band.UplinkChannels)) - dev.MACState.DesiredParameters.Channels = make([]*ttnpb.MACParameters_Channel, 0, len(band.UplinkChannels)+len(fp.UplinkChannels)) + if len(dev.GetMACSettings().GetFactoryPresetFrequencies()) > 0 { + dev.MACState.CurrentParameters.Channels = make([]*ttnpb.MACParameters_Channel, 0, len(dev.MACSettings.FactoryPresetFrequencies)) + for _, freq := range dev.MACSettings.FactoryPresetFrequencies { + dev.MACState.CurrentParameters.Channels = append(dev.MACState.CurrentParameters.Channels, &ttnpb.MACParameters_Channel{ + MinDataRateIndex: 0, + MaxDataRateIndex: ttnpb.DATA_RATE_15, + UplinkFrequency: freq, + DownlinkFrequency: freq, + EnableUplink: true, + }) + } + } else { + dev.MACState.CurrentParameters.Channels = make([]*ttnpb.MACParameters_Channel, len(band.UplinkChannels)) + for i, upCh := range band.UplinkChannels { + dev.MACState.CurrentParameters.Channels = append(dev.MACState.CurrentParameters.Channels, &ttnpb.MACParameters_Channel{ + MinDataRateIndex: upCh.MinDataRate, + MaxDataRateIndex: upCh.MaxDataRate, + UplinkFrequency: upCh.Frequency, + EnableUplink: true, + }) + } + for i, downCh := range band.DownlinkChannels { + dev.MACState.CurrentParameters.Channels[i].DownlinkFrequency = downCh.Frequency + } + } + dev.MACState.DesiredParameters.Channels = make([]*ttnpb.MACParameters_Channel, 0, len(band.UplinkChannels)+len(fp.UplinkChannels)) for i, upCh := range band.UplinkChannels { - ch := &ttnpb.MACParameters_Channel{ + dev.MACState.DesiredParameters.Channels = append(dev.MACState.DesiredParameters.Channels, &ttnpb.MACParameters_Channel{ MinDataRateIndex: upCh.MinDataRate, MaxDataRateIndex: upCh.MaxDataRate, UplinkFrequency: upCh.Frequency, - EnableUplink: true, - } - dev.MACState.CurrentParameters.Channels[i] = ch + }) } - for i, downCh := range band.DownlinkChannels { - // NOTE: len(band.DownlinkChannels) <= len(band.UplinkChannels) => i < len(dev.MACState.CurrentParameters.Channels) - dev.MACState.CurrentParameters.Channels[i].DownlinkFrequency = downCh.Frequency - } - - for _, ch := range dev.MACState.CurrentParameters.Channels { - chCopy := *ch - chCopy.EnableUplink = false - dev.MACState.DesiredParameters.Channels = append(dev.MACState.DesiredParameters.Channels, &chCopy) + dev.MACState.DesiredParameters.Channels[i].DownlinkFrequency = downCh.Frequency } outerUp: @@ -157,44 +275,5 @@ outerDown: panic("uplink/downlink channel length is inconsistent") } - dev.MACState.DesiredParameters.UplinkDwellTime = fp.DwellTime.GetUplinks() - dev.MACState.DesiredParameters.DownlinkDwellTime = fp.DwellTime.GetDownlinks() - - if dev.GetMACSettings().GetRx1Delay() != nil { - dev.MACState.DesiredParameters.Rx1Delay = dev.MACSettings.Rx1Delay.Value - } else if defaults.Rx1Delay != nil { - dev.MACState.DesiredParameters.Rx1Delay = defaults.Rx1Delay.Value - } - - if dev.GetMACSettings().GetRx2Frequency() != nil { - dev.MACState.DesiredParameters.Rx2Frequency = dev.MACSettings.Rx2Frequency.Value - } else if fp.Rx2Channel != nil { - dev.MACState.DesiredParameters.Rx2Frequency = fp.Rx2Channel.Frequency - } else if defaults.Rx2Frequency != nil { - dev.MACState.DesiredParameters.Rx2Frequency = defaults.Rx2Frequency.Value - } - - if dev.GetMACSettings().GetRx2DataRateIndex() != nil { - dev.MACState.DesiredParameters.Rx2DataRateIndex = dev.MACSettings.Rx2DataRateIndex.Value - } else if fp.DefaultRx2DataRate != nil { - dev.MACState.DesiredParameters.Rx2DataRateIndex = ttnpb.DataRateIndex(*fp.DefaultRx2DataRate) - } else if defaults.Rx2DataRateIndex != nil { - dev.MACState.DesiredParameters.Rx2DataRateIndex = defaults.Rx2DataRateIndex.Value - } - - if fp.PingSlot != nil { - dev.MACState.DesiredParameters.PingSlotFrequency = fp.PingSlot.Frequency - } - if fp.DefaultPingSlotDataRate != nil { - dev.MACState.DesiredParameters.PingSlotDataRateIndex = ttnpb.DataRateIndex(*fp.DefaultPingSlotDataRate) - } - if fp.MaxEIRP != nil && *fp.MaxEIRP > 0 { - dev.MACState.DesiredParameters.MaxEIRP = float32(math.Min(float64(dev.MACState.CurrentParameters.MaxEIRP), float64(*fp.MaxEIRP))) - } - - if dev.DefaultMACParameters != nil { - dev.MACState.CurrentParameters = deepcopy.Copy(*dev.DefaultMACParameters).(ttnpb.MACParameters) - } - return nil } From 69a419cd441e37a4562f1d02d11b34607ce0b31b Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 15 Feb 2019 12:48:46 +0100 Subject: [PATCH 19/40] ns: Adapt to API changes --- pkg/networkserver/adr.go | 21 +++++------ pkg/networkserver/downlink.go | 10 +++--- pkg/networkserver/downlink_internal_test.go | 14 ++++++++ pkg/networkserver/grpc_deviceregistry.go | 20 +++++------ pkg/networkserver/grpc_deviceregistry_test.go | 20 +++++++---- pkg/networkserver/grpc_gsns.go | 36 ++++++++++++++----- pkg/networkserver/grpc_gsns_test.go | 34 +++++++----------- pkg/networkserver/mac_reset_test.go | 12 ------- pkg/networkserver/utils.go | 10 +++--- pkg/networkserver/utils_internal_test.go | 4 +-- 10 files changed, 100 insertions(+), 81 deletions(-) diff --git a/pkg/networkserver/adr.go b/pkg/networkserver/adr.go index 290ebf0a32..0e6040fd2c 100644 --- a/pkg/networkserver/adr.go +++ b/pkg/networkserver/adr.go @@ -75,6 +75,16 @@ const optimalADRUplinkCount = 20 // DefaultADRMargin is the default ADR margin used if not specified in MACSettings of the device or NS-wide defaults. const DefaultADRMargin = 15 +func deviceADRMargin(dev *ttnpb.EndDevice, defaults ttnpb.MACSettings) float32 { + if dev.MACSettings != nil && dev.MACSettings.ADRMargin != nil { + return dev.MACSettings.ADRMargin.Value + } + if defaults.ADRMargin != nil { + return defaults.ADRMargin.Value + } + return DefaultADRMargin +} + func adaptDataRate(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults ttnpb.MACSettings) error { ups := dev.RecentADRUplinks if len(ups) == 0 { @@ -114,16 +124,7 @@ func adaptDataRate(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults ttn // minimum (floor) that we need to demodulate the signal. We subtract a // configurable margin, and an extra safety margin if we're afraid that we // don't have enough data for our decision. - margin := maxSNR - df - - if dev.MACSettings != nil && dev.MACSettings.ADRMargin != nil { - margin -= dev.MACSettings.ADRMargin.Value - } else if defaults.ADRMargin != nil { - margin -= defaults.ADRMargin.Value - } else { - margin -= DefaultADRMargin - } - + margin := maxSNR - df - deviceADRMargin(dev, defaults) if len(ups) < optimalADRUplinkCount { margin -= safetyMargin } diff --git a/pkg/networkserver/downlink.go b/pkg/networkserver/downlink.go index 24da95dd95..3cdff23212 100644 --- a/pkg/networkserver/downlink.go +++ b/pkg/networkserver/downlink.go @@ -52,13 +52,13 @@ var errNoDownlink = errors.Define("no_downlink", "no downlink to send") const DefaultClassCTimeout = 15 * time.Second func deviceClassCTimeout(dev *ttnpb.EndDevice, defaults ttnpb.MACSettings) time.Duration { - ret := DefaultClassCTimeout if dev.MACSettings != nil && dev.MACSettings.ClassCTimeout != nil { - ret = *dev.MACSettings.ClassCTimeout - } else if defaults.ClassCTimeout != nil { - ret = *defaults.ClassCTimeout + return *dev.MACSettings.ClassCTimeout } - return ret + if defaults.ClassCTimeout != nil { + return *defaults.ClassCTimeout + } + return DefaultClassCTimeout } // generateDownlink attempts to generate a downlink. diff --git a/pkg/networkserver/downlink_internal_test.go b/pkg/networkserver/downlink_internal_test.go index 017a5bff55..ee346fd970 100644 --- a/pkg/networkserver/downlink_internal_test.go +++ b/pkg/networkserver/downlink_internal_test.go @@ -2750,6 +2750,7 @@ func TestGenerateDownlink(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, LastNFCntDown: 41, SessionKeys: ttnpb.SessionKeys{ NwkSEncKey: &ttnpb.KeyEnvelope{ @@ -2804,6 +2805,7 @@ func TestGenerateDownlink(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, LastNFCntDown: 42, SessionKeys: ttnpb.SessionKeys{ NwkSEncKey: &ttnpb.KeyEnvelope{ @@ -2845,6 +2847,7 @@ func TestGenerateDownlink(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, SessionKeys: ttnpb.SessionKeys{ NwkSEncKey: &ttnpb.KeyEnvelope{ Key: NwkSEncKey[:], @@ -2910,6 +2913,7 @@ func TestGenerateDownlink(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, SessionKeys: ttnpb.SessionKeys{ NwkSEncKey: &ttnpb.KeyEnvelope{ Key: NwkSEncKey[:], @@ -2945,6 +2949,7 @@ func TestGenerateDownlink(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, SessionKeys: ttnpb.SessionKeys{ NwkSEncKey: &ttnpb.KeyEnvelope{ Key: NwkSEncKey[:], @@ -3016,6 +3021,7 @@ func TestGenerateDownlink(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, SessionKeys: ttnpb.SessionKeys{ NwkSEncKey: &ttnpb.KeyEnvelope{ Key: NwkSEncKey[:], @@ -3057,6 +3063,7 @@ func TestGenerateDownlink(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, SessionKeys: ttnpb.SessionKeys{ NwkSEncKey: &ttnpb.KeyEnvelope{ Key: NwkSEncKey[:], @@ -3135,6 +3142,7 @@ func TestGenerateDownlink(t *testing.T) { }, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, LastConfFCntDown: 42, SessionKeys: ttnpb.SessionKeys{ NwkSEncKey: &ttnpb.KeyEnvelope{ @@ -3171,6 +3179,7 @@ func TestGenerateDownlink(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, SessionKeys: ttnpb.SessionKeys{ NwkSEncKey: &ttnpb.KeyEnvelope{ Key: NwkSEncKey[:], @@ -3255,6 +3264,7 @@ func TestGenerateDownlink(t *testing.T) { }, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, LastConfFCntDown: 42, SessionKeys: ttnpb.SessionKeys{ NwkSEncKey: &ttnpb.KeyEnvelope{ @@ -3301,6 +3311,7 @@ func TestGenerateDownlink(t *testing.T) { LastDevStatusFCntUp: 4, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, LastFCntUp: 99, LastNFCntDown: 41, SessionKeys: ttnpb.SessionKeys{ @@ -3367,6 +3378,7 @@ func TestGenerateDownlink(t *testing.T) { }, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, LastFCntUp: 99, LastNFCntDown: 42, SessionKeys: ttnpb.SessionKeys{ @@ -3405,6 +3417,7 @@ func TestGenerateDownlink(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, LastNFCntDown: 41, SessionKeys: ttnpb.SessionKeys{ NwkSEncKey: &ttnpb.KeyEnvelope{ @@ -3469,6 +3482,7 @@ func TestGenerateDownlink(t *testing.T) { }, }, Session: &ttnpb.Session{ + DevAddr: DevAddr, LastNFCntDown: 42, SessionKeys: ttnpb.SessionKeys{ NwkSEncKey: &ttnpb.KeyEnvelope{ diff --git a/pkg/networkserver/grpc_deviceregistry.go b/pkg/networkserver/grpc_deviceregistry.go index 16953d978b..38fe221faf 100644 --- a/pkg/networkserver/grpc_deviceregistry.go +++ b/pkg/networkserver/grpc_deviceregistry.go @@ -98,34 +98,34 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest return &req.Device, req.FieldMask.Paths, nil } - if ttnpb.HasAnyField(req.FieldMask.Paths, "session.dev_addr") && req.Device.Session == nil || req.Device.Session.DevAddr.IsZero() { + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.dev_addr") && (req.Device.Session == nil || req.Device.Session.DevAddr.IsZero()) { return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.dev_addr") } - if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.session_key_id") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetSessionKeyID()) == 0 { + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.session_key_id") && (req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetSessionKeyID()) == 0) { return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.session_key_id") } - if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.f_nwk_s_int_key.key") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetFNwkSIntKey().GetKey()) == 0 { + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.f_nwk_s_int_key.key") && (req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetFNwkSIntKey().GetKey()) == 0) { return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.f_nwk_s_int_key.key") } - if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.f_nwk_s_int_key.kek_label") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetFNwkSIntKey().GetKEKLabel()) == 0 { + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.f_nwk_s_int_key.kek_label") && (req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetFNwkSIntKey().GetKEKLabel()) == 0) { return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.f_nwk_s_int_key.kek_label") } - if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.s_nwk_s_int_key.key") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetSNwkSIntKey().GetKey()) == 0 { + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.s_nwk_s_int_key.key") && (req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetSNwkSIntKey().GetKey()) == 0) { return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.s_nwk_s_int_key.key") } - if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.s_nwk_s_int_key.kek_label") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetSNwkSIntKey().GetKEKLabel()) == 0 { + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.s_nwk_s_int_key.kek_label") && (req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetSNwkSIntKey().GetKEKLabel()) == 0) { return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.s_nwk_s_int_key.kek_label") } - if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.nwk_s_enc_key.key") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetNwkSEncKey().GetKey()) == 0 { + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.nwk_s_enc_key.key") && (req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetNwkSEncKey().GetKey()) == 0) { return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.nwk_s_enc_key.key") } - if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.nwk_s_enc_key.kek_label") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetNwkSEncKey().GetKEKLabel()) == 0 { + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.nwk_s_enc_key.kek_label") && (req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetNwkSEncKey().GetKEKLabel()) == 0) { return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.nwk_s_enc_key.kek_label") } - if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.app_s_key.key") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetAppSKey().GetKey()) == 0 { + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.app_s_key.key") && (req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetAppSKey().GetKey()) == 0) { return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.app_s_key.key") } - if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.app_s_key.kek_label") && req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetAppSKey().GetKEKLabel()) == 0 { + if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.app_s_key.kek_label") && (req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetAppSKey().GetKEKLabel()) == 0) { return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.app_s_key.kek_label") } diff --git a/pkg/networkserver/grpc_deviceregistry_test.go b/pkg/networkserver/grpc_deviceregistry_test.go index de251955e6..9e7a8b8350 100644 --- a/pkg/networkserver/grpc_deviceregistry_test.go +++ b/pkg/networkserver/grpc_deviceregistry_test.go @@ -221,13 +221,13 @@ func TestDeviceRegistrySet(t *testing.T) { "frequency_plan_id", "lorawan_phy_version", "lorawan_version", + "mac_settings.supports_32_bit_f_cnt", "mac_settings.use_adr", "resets_f_cnt", "resets_join_nonces", "supports_class_b", "supports_class_c", "supports_join", - "uses_32_bit_f_cnt", }, }, }, @@ -267,13 +267,11 @@ func TestDeviceRegistrySet(t *testing.T) { "lorawan_phy_version", "lorawan_version", "mac_settings.adr_margin", - "mac_settings.use_adr", "resets_f_cnt", "resets_join_nonces", "supports_class_b", "supports_class_c", "supports_join", - "uses_32_bit_f_cnt", }) dev, sets, err := f(nil) @@ -283,16 +281,17 @@ func TestDeviceRegistrySet(t *testing.T) { "lorawan_phy_version", "lorawan_version", "mac_settings.adr_margin", - "mac_settings.use_adr", "resets_f_cnt", "resets_join_nonces", "supports_class_b", "supports_class_c", "supports_join", - "uses_32_bit_f_cnt", }) a.So(dev, should.Resemble, &ttnpb.EndDevice{ EndDeviceIdentifiers: ids, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0, + LoRaWANVersion: ttnpb.MAC_V1_0, SupportsJoin: true, MACSettings: &ttnpb.MACSettings{ ADRMargin: &pbtypes.FloatValue{Value: 4}, @@ -300,6 +299,9 @@ func TestDeviceRegistrySet(t *testing.T) { }) return &ttnpb.EndDevice{ EndDeviceIdentifiers: ids, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0, + LoRaWANVersion: ttnpb.MAC_V1_0, SupportsJoin: true, MACSettings: &ttnpb.MACSettings{ ADRMargin: &pbtypes.FloatValue{Value: 4}, @@ -309,6 +311,9 @@ func TestDeviceRegistrySet(t *testing.T) { Request: &ttnpb.SetEndDeviceRequest{ Device: ttnpb.EndDevice{ EndDeviceIdentifiers: ids, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0, + LoRaWANVersion: ttnpb.MAC_V1_0, SupportsJoin: true, MACSettings: &ttnpb.MACSettings{ ADRMargin: &pbtypes.FloatValue{Value: 4}, @@ -320,18 +325,19 @@ func TestDeviceRegistrySet(t *testing.T) { "lorawan_phy_version", "lorawan_version", "mac_settings.adr_margin", - "mac_settings.use_adr", "resets_f_cnt", "resets_join_nonces", "supports_class_b", "supports_class_c", "supports_join", - "uses_32_bit_f_cnt", }, }, }, Device: &ttnpb.EndDevice{ EndDeviceIdentifiers: ids, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0, + LoRaWANVersion: ttnpb.MAC_V1_0, SupportsJoin: true, MACSettings: &ttnpb.MACSettings{ ADRMargin: &pbtypes.FloatValue{Value: 4}, diff --git a/pkg/networkserver/grpc_gsns.go b/pkg/networkserver/grpc_gsns.go index 791bcd4dfd..c1d7f59071 100644 --- a/pkg/networkserver/grpc_gsns.go +++ b/pkg/networkserver/grpc_gsns.go @@ -105,13 +105,13 @@ func (ns *NetworkServer) matchDevice(ctx context.Context, up *ttnpb.UplinkMessag []string{ "frequency_plan_id", "lorawan_phy_version", + "mac_settings.resets_f_cnt", + "mac_settings.supports_32_bit_f_cnt", "mac_state", "pending_session", "recent_downlinks", "recent_uplinks", - "resets_f_cnt", "session", - "uses_32_bit_f_cnt", }, func(dev *ttnpb.EndDevice) bool { if dev.MACState == nil { @@ -182,9 +182,16 @@ func (ns *NetworkServer) matchDevice(ctx context.Context, up *ttnpb.UplinkMessag outer: for _, dev := range devs { + supports32BitFCnt := true + if dev.GetMACSettings().GetSupports32BitFCnt() != nil { + supports32BitFCnt = dev.MACSettings.Supports32BitFCnt.Value + } else if ns.defaultMACSettings.GetSupports32BitFCnt() != nil { + supports32BitFCnt = ns.defaultMACSettings.Supports32BitFCnt.Value + } + fCnt := pld.FCnt switch { - case !dev.Uses32BitFCnt, fCnt > dev.matchedSession.LastFCntUp, fCnt == 0: + case !supports32BitFCnt, fCnt > dev.matchedSession.LastFCntUp, fCnt == 0: case fCnt > dev.matchedSession.LastFCntUp&0xffff: fCnt |= dev.matchedSession.LastFCntUp &^ 0xffff case dev.matchedSession.LastFCntUp < 0xffff0000: @@ -198,11 +205,18 @@ outer: "uplink_f_cnt_up", pld.FCnt, )) + resetsFCnt := false + if dev.GetMACSettings().GetResetsFCnt() != nil { + resetsFCnt = dev.MACSettings.ResetsFCnt.Value + } else if ns.defaultMACSettings.GetResetsFCnt() != nil { + resetsFCnt = ns.defaultMACSettings.ResetsFCnt.Value + } + gap := uint32(math.MaxUint32) if fCnt == 0 && dev.matchedSession.LastFCntUp == 0 && (len(dev.RecentUplinks) == 0 || dev.PendingSession != nil) { gap = 0 - } else if !dev.ResetsFCnt { + } else if !resetsFCnt { if fCnt <= dev.matchedSession.LastFCntUp { logger.Debug("FCnt too low, skipping...") continue outer @@ -229,7 +243,7 @@ outer: gap: gap, fCnt: fCnt, }) - if dev.ResetsFCnt && fCnt != pld.FCnt { + if resetsFCnt && fCnt != pld.FCnt { matching = append(matching, device{ EndDevice: dev.EndDevice, matchedSession: dev.matchedSession, @@ -448,7 +462,6 @@ func (ns *NetworkServer) handleUplink(ctx context.Context, up *ttnpb.UplinkMessa var handleErr bool stored, err := ns.devices.SetByID(ctx, matched.EndDeviceIdentifiers.ApplicationIdentifiers, matched.EndDeviceIdentifiers.DeviceID, []string{ - "default_mac_parameters", "downlink_margin", "frequency_plan_id", "last_dev_status_received_at", @@ -458,7 +471,6 @@ func (ns *NetworkServer) handleUplink(ctx context.Context, up *ttnpb.UplinkMessa "mac_state", "pending_session", "recent_uplinks", - "resets_f_cnt", "session", "supports_join", }, @@ -480,7 +492,14 @@ func (ns *NetworkServer) handleUplink(ctx context.Context, up *ttnpb.UplinkMessa handleErr = true return nil, nil, errOutdatedData } - if storedSes.GetLastFCntUp() > ses.LastFCntUp && !stored.ResetsFCnt { + + resetsFCnt := false + if stored.GetMACSettings().GetResetsFCnt() != nil { + resetsFCnt = stored.MACSettings.ResetsFCnt.Value + } else if ns.defaultMACSettings.GetResetsFCnt() != nil { + resetsFCnt = ns.defaultMACSettings.ResetsFCnt.Value + } + if storedSes.GetLastFCntUp() > ses.LastFCntUp && !resetsFCnt { logger.WithFields(log.Fields( "stored_f_cnt", storedSes.GetLastFCntUp(), "got_f_cnt", ses.LastFCntUp, @@ -829,7 +848,6 @@ func (ns *NetworkServer) handleJoin(ctx context.Context, up *ttnpb.UplinkMessage var resetErr bool dev, err = ns.devices.SetByID(ctx, dev.EndDeviceIdentifiers.ApplicationIdentifiers, dev.EndDeviceIdentifiers.DeviceID, []string{ - "default_mac_parameters", "frequency_plan_id", "lorawan_phy_version", "lorawan_version", diff --git a/pkg/networkserver/grpc_gsns_test.go b/pkg/networkserver/grpc_gsns_test.go index 269bae8c52..1d2e9226d9 100644 --- a/pkg/networkserver/grpc_gsns_test.go +++ b/pkg/networkserver/grpc_gsns_test.go @@ -183,7 +183,6 @@ func handleUplinkTest() func(t *testing.T) { }, LoRaWANVersion: ttnpb.MAC_V1_1, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - MACSettings: &ttnpb.MACSettings{}, Session: &ttnpb.Session{ DevAddr: DevAddr, SessionKeys: ttnpb.SessionKeys{ @@ -248,7 +247,6 @@ func handleUplinkTest() func(t *testing.T) { }, LoRaWANVersion: ttnpb.MAC_V1_1, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - MACSettings: &ttnpb.MACSettings{}, Session: &ttnpb.Session{ DevAddr: DevAddr, SessionKeys: ttnpb.SessionKeys{ @@ -300,7 +298,6 @@ func handleUplinkTest() func(t *testing.T) { { "1.0/unconfirmed/no ack/FCnt does not reset", &ttnpb.EndDevice{ - MACSettings: &ttnpb.MACSettings{}, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_0, CurrentParameters: ttnpb.MACParameters{ @@ -329,7 +326,6 @@ func handleUplinkTest() func(t *testing.T) { }, LoRaWANVersion: ttnpb.MAC_V1_0, LoRaWANPHYVersion: ttnpb.PHY_V1_0, - ResetsFCnt: true, EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ ApplicationID: ApplicationID, @@ -376,7 +372,9 @@ func handleUplinkTest() func(t *testing.T) { { "1.0/unconfirmed/no ack/FCnt resets", &ttnpb.EndDevice{ - MACSettings: &ttnpb.MACSettings{}, + MACSettings: &ttnpb.MACSettings{ + ResetsFCnt: &pbtypes.BoolValue{Value: true}, + }, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_0, CurrentParameters: ttnpb.MACParameters{ @@ -405,7 +403,6 @@ func handleUplinkTest() func(t *testing.T) { }, LoRaWANVersion: ttnpb.MAC_V1_0, LoRaWANPHYVersion: ttnpb.PHY_V1_0, - ResetsFCnt: true, EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ ApplicationID: ApplicationID, @@ -452,7 +449,6 @@ func handleUplinkTest() func(t *testing.T) { { "1.0/confirmed/ack/FCnt does not reset", &ttnpb.EndDevice{ - MACSettings: &ttnpb.MACSettings{}, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_0, PendingApplicationDownlink: ttnpb.NewPopulatedApplicationDownlink(test.Randy, false), @@ -533,7 +529,9 @@ func handleUplinkTest() func(t *testing.T) { { "1.0/confirmed/ack/FCnt resets", &ttnpb.EndDevice{ - MACSettings: &ttnpb.MACSettings{}, + MACSettings: &ttnpb.MACSettings{ + ResetsFCnt: &pbtypes.BoolValue{Value: true}, + }, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_0, PendingApplicationDownlink: ttnpb.NewPopulatedApplicationDownlink(test.Randy, false), @@ -563,7 +561,6 @@ func handleUplinkTest() func(t *testing.T) { }, LoRaWANVersion: ttnpb.MAC_V1_0, LoRaWANPHYVersion: ttnpb.PHY_V1_0, - ResetsFCnt: true, EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ ApplicationID: ApplicationID, @@ -615,7 +612,6 @@ func handleUplinkTest() func(t *testing.T) { { "1.1/unconfirmed/no ack/FCnt does not reset", &ttnpb.EndDevice{ - MACSettings: &ttnpb.MACSettings{}, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_1, CurrentParameters: ttnpb.MACParameters{ @@ -702,7 +698,6 @@ func handleUplinkTest() func(t *testing.T) { { "1.1/confirmed/ack/FCnt does not reset", &ttnpb.EndDevice{ - MACSettings: &ttnpb.MACSettings{}, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_1, PendingApplicationDownlink: ttnpb.NewPopulatedApplicationDownlink(test.Randy, false), @@ -801,7 +796,9 @@ func handleUplinkTest() func(t *testing.T) { { "1.1/unconfirmed/no ack/FCnt resets", &ttnpb.EndDevice{ - MACSettings: &ttnpb.MACSettings{}, + MACSettings: &ttnpb.MACSettings{ + ResetsFCnt: &pbtypes.BoolValue{Value: true}, + }, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_1, CurrentParameters: ttnpb.MACParameters{ @@ -830,7 +827,6 @@ func handleUplinkTest() func(t *testing.T) { }, LoRaWANVersion: ttnpb.MAC_V1_1, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - ResetsFCnt: true, EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ ApplicationID: ApplicationID, @@ -889,7 +885,9 @@ func handleUplinkTest() func(t *testing.T) { { "1.1/confirmed/ack/FCnt resets", &ttnpb.EndDevice{ - MACSettings: &ttnpb.MACSettings{}, + MACSettings: &ttnpb.MACSettings{ + ResetsFCnt: &pbtypes.BoolValue{Value: true}, + }, MACState: &ttnpb.MACState{ LoRaWANVersion: ttnpb.MAC_V1_1, PendingApplicationDownlink: ttnpb.NewPopulatedApplicationDownlink(test.Randy, false), @@ -919,7 +917,6 @@ func handleUplinkTest() func(t *testing.T) { }, LoRaWANVersion: ttnpb.MAC_V1_1, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, - ResetsFCnt: true, EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ ApplicationID: ApplicationID, @@ -1262,7 +1259,7 @@ func handleUplinkTest() func(t *testing.T) { errch <- err }() - if !pb.ResetsFCnt { + if pb.GetMACSettings().GetResetsFCnt() == nil || !pb.MACSettings.ResetsFCnt.Value { close(deduplicationDoneCh) _ = sendUplinkDuplicates(t, ns, collectionDoneCh, ctx, tc.UplinkMessage, DuplicateCount) close(collectionDoneCh) @@ -1439,7 +1436,6 @@ func handleJoinTest() func(t *testing.T) { DeviceID: DeviceID, }, FrequencyPlanID: test.EUFrequencyPlanID, - MACSettings: &ttnpb.MACSettings{}, }, func() *ttnpb.UplinkMessage { msg := ttnpb.NewPopulatedUplinkMessageJoinRequest(test.Randy) @@ -1467,7 +1463,6 @@ func handleJoinTest() func(t *testing.T) { FrequencyPlanID: test.EUFrequencyPlanID, Session: ttnpb.NewPopulatedSession(test.Randy, false), MACState: ttnpb.NewPopulatedMACState(test.Randy, false), - MACSettings: &ttnpb.MACSettings{}, }, func() *ttnpb.UplinkMessage { msg := ttnpb.NewPopulatedUplinkMessageJoinRequest(test.Randy) @@ -1495,7 +1490,6 @@ func handleJoinTest() func(t *testing.T) { FrequencyPlanID: test.EUFrequencyPlanID, Session: ttnpb.NewPopulatedSession(test.Randy, false), MACState: ttnpb.NewPopulatedMACState(test.Randy, false), - MACSettings: &ttnpb.MACSettings{}, }, func() *ttnpb.UplinkMessage { msg := ttnpb.NewPopulatedUplinkMessageJoinRequest(test.Randy) @@ -1523,7 +1517,6 @@ func handleJoinTest() func(t *testing.T) { FrequencyPlanID: test.EUFrequencyPlanID, Session: ttnpb.NewPopulatedSession(test.Randy, false), MACState: ttnpb.NewPopulatedMACState(test.Randy, false), - MACSettings: &ttnpb.MACSettings{}, }, func() *ttnpb.UplinkMessage { msg := ttnpb.NewPopulatedUplinkMessageJoinRequest(test.Randy) @@ -1551,7 +1544,6 @@ func handleJoinTest() func(t *testing.T) { FrequencyPlanID: test.EUFrequencyPlanID, Session: ttnpb.NewPopulatedSession(test.Randy, false), MACState: ttnpb.NewPopulatedMACState(test.Randy, false), - MACSettings: &ttnpb.MACSettings{}, }, func() *ttnpb.UplinkMessage { msg := ttnpb.NewPopulatedUplinkMessageJoinRequest(test.Randy) diff --git a/pkg/networkserver/mac_reset_test.go b/pkg/networkserver/mac_reset_test.go index 583108e665..799fd337d6 100644 --- a/pkg/networkserver/mac_reset_test.go +++ b/pkg/networkserver/mac_reset_test.go @@ -55,9 +55,6 @@ func TestHandleResetInd(t *testing.T) { { Name: "empty queue", Device: &ttnpb.EndDevice{ - DefaultMACParameters: &ttnpb.MACParameters{ - MaxEIRP: 42, - }, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, SupportsJoin: false, FrequencyPlanID: test.EUFrequencyPlanID, @@ -69,9 +66,6 @@ func TestHandleResetInd(t *testing.T) { }, Expected: func() *ttnpb.EndDevice { dev := &ttnpb.EndDevice{ - DefaultMACParameters: &ttnpb.MACParameters{ - MaxEIRP: 42, - }, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, SupportsJoin: false, FrequencyPlanID: test.EUFrequencyPlanID, @@ -107,9 +101,6 @@ func TestHandleResetInd(t *testing.T) { { Name: "non-empty queue", Device: &ttnpb.EndDevice{ - DefaultMACParameters: &ttnpb.MACParameters{ - MaxEIRP: 42, - }, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, SupportsJoin: false, FrequencyPlanID: test.EUFrequencyPlanID, @@ -125,9 +116,6 @@ func TestHandleResetInd(t *testing.T) { }, Expected: func() *ttnpb.EndDevice { dev := &ttnpb.EndDevice{ - DefaultMACParameters: &ttnpb.MACParameters{ - MaxEIRP: 42, - }, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, SupportsJoin: false, FrequencyPlanID: test.EUFrequencyPlanID, diff --git a/pkg/networkserver/utils.go b/pkg/networkserver/utils.go index c001f53ed1..fc43053ac6 100644 --- a/pkg/networkserver/utils.go +++ b/pkg/networkserver/utils.go @@ -110,9 +110,9 @@ func resetMACState(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults ttn } dev.MACState.DesiredParameters.Rx1Delay = dev.MACState.CurrentParameters.Rx1Delay if dev.GetMACSettings().GetDesiredRx1Delay() != nil { - dev.MACState.DesiredParameters.Rx1Delay = dev.MACSettings.Rx1Delay.Value + dev.MACState.DesiredParameters.Rx1Delay = dev.MACSettings.DesiredRx1Delay.Value } else if defaults.DesiredRx1Delay != nil { - dev.MACState.DesiredParameters.Rx1Delay = defaults.Rx1Delay.Value + dev.MACState.DesiredParameters.Rx1Delay = defaults.DesiredRx1Delay.Value } dev.MACState.CurrentParameters.Rx1DataRateOffset = 0 @@ -215,8 +215,8 @@ func resetMACState(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults ttn }) } } else { - dev.MACState.CurrentParameters.Channels = make([]*ttnpb.MACParameters_Channel, len(band.UplinkChannels)) - for i, upCh := range band.UplinkChannels { + dev.MACState.CurrentParameters.Channels = make([]*ttnpb.MACParameters_Channel, 0, len(band.UplinkChannels)) + for _, upCh := range band.UplinkChannels { dev.MACState.CurrentParameters.Channels = append(dev.MACState.CurrentParameters.Channels, &ttnpb.MACParameters_Channel{ MinDataRateIndex: upCh.MinDataRate, MaxDataRateIndex: upCh.MaxDataRate, @@ -230,7 +230,7 @@ func resetMACState(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults ttn } dev.MACState.DesiredParameters.Channels = make([]*ttnpb.MACParameters_Channel, 0, len(band.UplinkChannels)+len(fp.UplinkChannels)) - for i, upCh := range band.UplinkChannels { + for _, upCh := range band.UplinkChannels { dev.MACState.DesiredParameters.Channels = append(dev.MACState.DesiredParameters.Channels, &ttnpb.MACParameters_Channel{ MinDataRateIndex: upCh.MinDataRate, MaxDataRateIndex: upCh.MaxDataRate, diff --git a/pkg/networkserver/utils_internal_test.go b/pkg/networkserver/utils_internal_test.go index e999d8b0a2..2dacd274b9 100644 --- a/pkg/networkserver/utils_internal_test.go +++ b/pkg/networkserver/utils_internal_test.go @@ -41,7 +41,7 @@ func TestResetMACState(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, MACSettings: &ttnpb.MACSettings{ - Rx1Delay: &ttnpb.MACSettings_RxDelayValue{ + DesiredRx1Delay: &ttnpb.MACSettings_RxDelayValue{ Value: ttnpb.RX_DELAY_13, }, }, @@ -192,7 +192,7 @@ func TestResetMACState(t *testing.T) { LoRaWANVersion: ttnpb.MAC_V1_1, LoRaWANPHYVersion: ttnpb.PHY_V1_1_REV_B, MACSettings: &ttnpb.MACSettings{ - Rx1Delay: &ttnpb.MACSettings_RxDelayValue{ + DesiredRx1Delay: &ttnpb.MACSettings_RxDelayValue{ Value: ttnpb.RX_DELAY_13, }, }, From 56fab96f6ae46d9c6392ea9e3a0cb3a06a52f19a Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 19 Feb 2019 10:06:18 +0100 Subject: [PATCH 20/40] ns: Fix fieldmask check --- pkg/networkserver/grpc_deviceregistry.go | 39 +-- pkg/networkserver/grpc_deviceregistry_test.go | 226 +++++++++++++++++- 2 files changed, 237 insertions(+), 28 deletions(-) diff --git a/pkg/networkserver/grpc_deviceregistry.go b/pkg/networkserver/grpc_deviceregistry.go index 38fe221faf..5d1298f6c5 100644 --- a/pkg/networkserver/grpc_deviceregistry.go +++ b/pkg/networkserver/grpc_deviceregistry.go @@ -17,6 +17,7 @@ package networkserver import ( "bytes" "context" + "strings" "time" pbtypes "github.com/gogo/protobuf/types" @@ -59,23 +60,12 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest "queued_application_downlinks", ) } - if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_state.desired_parameters") { - gets = append(gets, - "mac_state.current_parameters", - "mac_state.device_class", - ) - } - if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_state.current_parameters") { - gets = append(gets, - "mac_state.desired_parameters", - "mac_state.device_class", - ) - } var addDownlinkTask bool dev, err := ns.devices.SetByID(ctx, req.Device.EndDeviceIdentifiers.ApplicationIdentifiers, req.Device.EndDeviceIdentifiers.DeviceID, gets, func(dev *ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error) { if err := ttnpb.ProhibitFields(req.FieldMask.Paths, - "mac_state", + "mac_state.current_parameters", + "mac_state.desired_parameters", "pending_session", ); err != nil { return nil, nil, errInvalidFieldMask.WithCause(err) @@ -89,8 +79,6 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest } addDownlinkTask = ttnpb.HasAnyField(req.FieldMask.Paths, - "mac_state.current_parameters", - "mac_state.desired_parameters", "mac_state.device_class", "queued_application_downlinks", ) && req.Device.MACState.DeviceClass != ttnpb.CLASS_A && @@ -231,8 +219,17 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest } } - if req.Device.SupportsJoin && !ttnpb.HasAnyField(sets, "session") { - return &req.Device, sets, nil + if req.Device.SupportsJoin { + var hasSession bool + for _, p := range sets { + if p == "session" || strings.HasPrefix(p, "session.") { + hasSession = true + break + } + } + if !hasSession { + return &req.Device, sets, nil + } } if err := ttnpb.RequireFields(sets, @@ -272,7 +269,12 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest // TODO: Encrypt (https://github.com/TheThingsIndustries/lorawan-stack/issues/1562) req.Device.Session.SNwkSIntKey = req.Device.Session.FNwkSIntKey req.Device.Session.NwkSEncKey = req.Device.Session.FNwkSIntKey - sets = append(sets, "session.keys.s_nwk_s_int_key", "session.keys.nwk_s_enc_key") + sets = append(sets, + "session.keys.nwk_s_enc_key.kek_label", + "session.keys.nwk_s_enc_key.key", + "session.keys.s_nwk_s_int_key.kek_label", + "session.keys.s_nwk_s_int_key.key", + ) } if ttnpb.HasAnyField(sets, "session.started_at") && req.Device.GetSession().GetStartedAt().IsZero() { @@ -285,6 +287,7 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest if err := resetMACState(&req.Device, ns.FrequencyPlans, ns.defaultMACSettings); err != nil { return nil, nil, err } + sets = append(sets, "mac_state") addDownlinkTask = req.Device.MACState.DeviceClass != ttnpb.CLASS_A && (len(req.Device.QueuedApplicationDownlinks) > 0 || !req.Device.MACState.CurrentParameters.Equal(req.Device.MACState.DesiredParameters)) diff --git a/pkg/networkserver/grpc_deviceregistry_test.go b/pkg/networkserver/grpc_deviceregistry_test.go index 9e7a8b8350..a84c3cf7fb 100644 --- a/pkg/networkserver/grpc_deviceregistry_test.go +++ b/pkg/networkserver/grpc_deviceregistry_test.go @@ -25,8 +25,10 @@ import ( "go.thethings.network/lorawan-stack/pkg/auth/rights" "go.thethings.network/lorawan-stack/pkg/component" "go.thethings.network/lorawan-stack/pkg/errors" + "go.thethings.network/lorawan-stack/pkg/frequencyplans" . "go.thethings.network/lorawan-stack/pkg/networkserver" "go.thethings.network/lorawan-stack/pkg/ttnpb" + "go.thethings.network/lorawan-stack/pkg/types" "go.thethings.network/lorawan-stack/pkg/unique" "go.thethings.network/lorawan-stack/pkg/util/test" "go.thethings.network/lorawan-stack/pkg/util/test/assertions/should" @@ -297,16 +299,7 @@ func TestDeviceRegistrySet(t *testing.T) { ADRMargin: &pbtypes.FloatValue{Value: 4}, }, }) - return &ttnpb.EndDevice{ - EndDeviceIdentifiers: ids, - FrequencyPlanID: test.EUFrequencyPlanID, - LoRaWANPHYVersion: ttnpb.PHY_V1_0, - LoRaWANVersion: ttnpb.MAC_V1_0, - SupportsJoin: true, - MACSettings: &ttnpb.MACSettings{ - ADRMargin: &pbtypes.FloatValue{Value: 4}, - }, - }, nil + return dev, nil }, Request: &ttnpb.SetEndDeviceRequest{ Device: ttnpb.EndDevice{ @@ -348,6 +341,218 @@ func TestDeviceRegistrySet(t *testing.T) { return a.So(test.MustCounterFromContext(ctx, setByIDCallKey{}), should.Equal, 1) }, }, + + { + // https://github.com/TheThingsNetwork/lorawan-stack/issues/104#issuecomment-465074076 + Name: "Create OTAA device with existing session", + ContextFunc: func(ctx context.Context) context.Context { + return rights.NewContext(ctx, rights.Rights{ + ApplicationRights: map[string]*ttnpb.Rights{ + unique.ID(ctx, ids.ApplicationIdentifiers): { + Rights: []ttnpb.Right{ + ttnpb.RIGHT_APPLICATION_DEVICES_WRITE, + }, + }, + }, + }) + }, + SetByIDFunc: func(ctx context.Context, appID ttnpb.ApplicationIdentifiers, devID string, gets []string, f func(*ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error)) (*ttnpb.EndDevice, error) { + defer test.MustIncrementContextCounter(ctx, setByIDCallKey{}, 1) + a := assertions.New(test.MustTFromContext(ctx)) + a.So(appID, should.Resemble, ids.ApplicationIdentifiers) + a.So(devID, should.Equal, DeviceID) + a.So(gets, should.HaveSameElementsDeep, []string{ + "frequency_plan_id", + "lorawan_phy_version", + "lorawan_version", + "mac_settings.use_adr", + "mac_settings.supports_32_bit_f_cnt", + "resets_f_cnt", + "resets_join_nonces", + "root_keys.app_key.key", + "session.dev_addr", + "session.keys.app_s_key.key", + "session.keys.f_nwk_s_int_key.key", + "session.last_f_cnt_up", + "session.last_n_f_cnt_down", + "session.started_at", + "supports_join", + }) + + dev, sets, err := f(nil) + a.So(err, should.BeNil) + a.So(sets, should.HaveSameElementsDeep, []string{ + "frequency_plan_id", + "lorawan_phy_version", + "lorawan_version", + "mac_settings.supports_32_bit_f_cnt", + "mac_settings.use_adr", + "mac_state", + "resets_f_cnt", + "resets_join_nonces", + "root_keys.app_key.key", + "session.dev_addr", + "session.keys.app_s_key.key", + "session.keys.f_nwk_s_int_key.key", + "session.keys.nwk_s_enc_key.kek_label", + "session.keys.nwk_s_enc_key.key", + "session.keys.s_nwk_s_int_key.kek_label", + "session.keys.s_nwk_s_int_key.key", + "session.last_f_cnt_up", + "session.last_n_f_cnt_down", + "session.started_at", + "supports_join", + }) + + expected := &ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: ids.DeviceID, + ApplicationIdentifiers: ids.ApplicationIdentifiers, + DevAddr: &types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, + }, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0_2_REV_B, + LoRaWANVersion: ttnpb.MAC_V1_0_2, + SupportsJoin: true, + MACSettings: &ttnpb.MACSettings{ + Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, + UseADR: &pbtypes.BoolValue{Value: true}, + }, + RootKeys: &ttnpb.RootKeys{ + AppKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x4f, 0x93, 0x95, 0x95, 0xce, 0x83, 0x28, 0x8a, 0xfe, 0xf8, 0x1b, 0xd8, 0x81, 0xc3, 0xc3, 0x6e}, + }, + }, + Session: &ttnpb.Session{ + StartedAt: time.Unix(0, 42).UTC(), + DevAddr: types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, + LastFCntUp: 45872, + LastNFCntDown: 1880, + SessionKeys: ttnpb.SessionKeys{ + AppSKey: &ttnpb.KeyEnvelope{ + Key: []byte{0xa1, 0x5b, 0xef, 0x4a, 0x32, 0x33, 0x27, 0x4a, 0xe9, 0x17, 0xe4, 0xaf, 0xb1, 0x90, 0x55, 0xf2}, + }, + FNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, + }, + NwkSEncKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, + }, + SNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, + }, + }, + }, + } + err = ResetMACState(expected, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{}) + if !a.So(err, should.BeNil) { + t.Fatalf("Failed to reset MAC state: %s", err) + } + a.So(dev, should.Resemble, expected) + return dev, nil + }, + Request: &ttnpb.SetEndDeviceRequest{ + Device: ttnpb.EndDevice{ + EndDeviceIdentifiers: ids, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0_2_REV_B, + LoRaWANVersion: ttnpb.MAC_V1_0_2, + SupportsJoin: true, + MACSettings: &ttnpb.MACSettings{ + Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, + UseADR: &pbtypes.BoolValue{Value: true}, + }, + RootKeys: &ttnpb.RootKeys{ + AppKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x4f, 0x93, 0x95, 0x95, 0xce, 0x83, 0x28, 0x8a, 0xfe, 0xf8, 0x1b, 0xd8, 0x81, 0xc3, 0xc3, 0x6e}, + }, + }, + Session: &ttnpb.Session{ + StartedAt: time.Unix(0, 42).UTC(), + DevAddr: types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, + LastFCntUp: 45872, + LastNFCntDown: 1880, + SessionKeys: ttnpb.SessionKeys{ + AppSKey: &ttnpb.KeyEnvelope{ + Key: []byte{0xa1, 0x5b, 0xef, 0x4a, 0x32, 0x33, 0x27, 0x4a, 0xe9, 0x17, 0xe4, 0xaf, 0xb1, 0x90, 0x55, 0xf2}, + }, + FNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, + }, + }, + }, + }, + FieldMask: pbtypes.FieldMask{ + Paths: []string{ + "frequency_plan_id", + "lorawan_phy_version", + "lorawan_version", + "mac_settings.use_adr", + "mac_settings.supports_32_bit_f_cnt", + "resets_f_cnt", + "resets_join_nonces", + "root_keys.app_key.key", + "session.dev_addr", + "session.keys.app_s_key.key", + "session.keys.f_nwk_s_int_key.key", + "session.last_f_cnt_up", + "session.last_n_f_cnt_down", + "session.started_at", + "supports_join", + }, + }, + }, + Device: func() *ttnpb.EndDevice { + expected := &ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: ids.DeviceID, + ApplicationIdentifiers: ids.ApplicationIdentifiers, + DevAddr: &types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, + }, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0_2_REV_B, + LoRaWANVersion: ttnpb.MAC_V1_0_2, + SupportsJoin: true, + MACSettings: &ttnpb.MACSettings{ + Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, + UseADR: &pbtypes.BoolValue{Value: true}, + }, + RootKeys: &ttnpb.RootKeys{ + AppKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x4f, 0x93, 0x95, 0x95, 0xce, 0x83, 0x28, 0x8a, 0xfe, 0xf8, 0x1b, 0xd8, 0x81, 0xc3, 0xc3, 0x6e}, + }, + }, + Session: &ttnpb.Session{ + StartedAt: time.Unix(0, 42).UTC(), + DevAddr: types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, + LastFCntUp: 45872, + LastNFCntDown: 1880, + SessionKeys: ttnpb.SessionKeys{ + AppSKey: &ttnpb.KeyEnvelope{ + Key: []byte{0xa1, 0x5b, 0xef, 0x4a, 0x32, 0x33, 0x27, 0x4a, 0xe9, 0x17, 0xe4, 0xaf, 0xb1, 0x90, 0x55, 0xf2}, + }, + FNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, + }, + NwkSEncKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, + }, + SNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, + }, + }, + }, + } + if err := ResetMACState(expected, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{}); err != nil { + t.Fatalf("Failed to reset MAC state: %s", err) + } + return expected + }(), + ContextAssertion: func(ctx context.Context) bool { + a := assertions.New(test.MustTFromContext(ctx)) + return a.So(test.MustCounterFromContext(ctx, setByIDCallKey{}), should.Equal, 1) + }, + }, } { t.Run(tc.Name, func(t *testing.T) { a := assertions.New(t) @@ -362,6 +567,7 @@ func TestDeviceRegistrySet(t *testing.T) { CooldownWindow: 42, DownlinkTasks: &MockDownlinkTaskQueue{}, })).(*NetworkServer) + ns.FrequencyPlans = frequencyplans.NewStore(test.FrequencyPlansFetcher) ns.AddContextFiller(tc.ContextFunc) ns.AddContextFiller(func(ctx context.Context) context.Context { From 8b0f17233e87160355b5a163e179b882b7184502 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 15 Feb 2019 13:36:15 +0100 Subject: [PATCH 21/40] ns: Unwrap encrypted keys --- pkg/networkserver/downlink.go | 43 +++++++------- pkg/networkserver/downlink_internal_test.go | 62 +++++++++----------- pkg/networkserver/grpc_gsns.go | 45 +++++++++----- pkg/networkserver/networkserver_util_test.go | 5 +- 4 files changed, 83 insertions(+), 72 deletions(-) diff --git a/pkg/networkserver/downlink.go b/pkg/networkserver/downlink.go index 3cdff23212..20cad79fe6 100644 --- a/pkg/networkserver/downlink.go +++ b/pkg/networkserver/downlink.go @@ -27,7 +27,6 @@ import ( "go.thethings.network/lorawan-stack/pkg/encoding/lorawan" "go.thethings.network/lorawan-stack/pkg/errors" "go.thethings.network/lorawan-stack/pkg/events" - "go.thethings.network/lorawan-stack/pkg/frequencyplans" "go.thethings.network/lorawan-stack/pkg/log" "go.thethings.network/lorawan-stack/pkg/ttnpb" "go.thethings.network/lorawan-stack/pkg/types" @@ -72,7 +71,7 @@ func deviceClassCTimeout(dev *ttnpb.EndDevice, defaults ttnpb.MACSettings) time. // For example, a sequence of 'NewChannel' MAC commands could be generated for a // device operating in a region where a fixed channel plan is defined in case // dev.MACState.CurrentParameters.Channels is not equal to dev.MACState.DesiredParameters.Channels. -func generateDownlink(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, maxUpLen uint16, fps *frequencyplans.Store, defaults ttnpb.MACSettings) ([]byte, *ttnpb.ApplicationDownlink, error) { +func (ns *NetworkServer) generateDownlink(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, maxUpLen uint16) ([]byte, *ttnpb.ApplicationDownlink, error) { if dev.MACState == nil { return nil, nil, errUnknownMACState } @@ -107,7 +106,7 @@ func generateDownlink(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, max dev.MACState.PendingRequests = dev.MACState.PendingRequests[:0] - maxDownLen, maxUpLen, ok, err := enqueueLinkADRReq(ctx, dev, maxDownLen, maxUpLen, fps) + maxDownLen, maxUpLen, ok, err := enqueueLinkADRReq(ctx, dev, maxDownLen, maxUpLen, ns.FrequencyPlans) if err != nil { return nil, nil, err } @@ -118,7 +117,7 @@ func generateDownlink(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, max enqueueDutyCycleReq, enqueueRxParamSetupReq, func(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen uint16, maxUpLen uint16) (uint16, uint16, bool) { - return enqueueDevStatusReq(ctx, dev, maxDownLen, maxUpLen, defaults) + return enqueueDevStatusReq(ctx, dev, maxDownLen, maxUpLen, ns.defaultMACSettings) }, enqueueRxTimingSetupReq, enqueuePingSlotChannelReq, @@ -224,10 +223,15 @@ outer: var key types.AES128Key if dev.Session.NwkSEncKey.KEKLabel != "" { - // TODO: (https://github.com/TheThingsNetwork/lorawan-stack/issues/5) - panic("unsupported") + b, err := ns.KeyVault.Unwrap(dev.Session.NwkSEncKey.Key, dev.Session.NwkSEncKey.KEKLabel) + if err != nil { + logger.WithField("kek_label", dev.Session.NwkSEncKey.KEKLabel).WithError(err).Error("Failed to unwrap NwkSEncKey") + return nil, nil, err + } + copy(key[:], b) + } else { + copy(key[:], dev.Session.NwkSEncKey.Key[:]) } - copy(key[:], dev.Session.NwkSEncKey.Key[:]) var err error cmdBuf, err = crypto.EncryptDownlink(key, *dev.EndDeviceIdentifiers.DevAddr, pld.FHDR.FCnt, cmdBuf) @@ -255,7 +259,7 @@ outer: break case dev.MACState.DeviceClass == ttnpb.CLASS_C && - dev.MACState.LastConfirmedDownlinkAt.Add(deviceClassCTimeout(dev, defaults)).After(time.Now()): + dev.MACState.LastConfirmedDownlinkAt.Add(deviceClassCTimeout(dev, ns.defaultMACSettings)).After(time.Now()): return nil, nil, errScheduleTooSoon default: @@ -281,10 +285,15 @@ outer: return nil, nil, errUnknownSNwkSIntKey } if dev.Session.SNwkSIntKey.KEKLabel != "" { - // TODO: https://github.com/TheThingsNetwork/lorawan-stack/issues/5 - panic("unsupported") + b, err := ns.KeyVault.Unwrap(dev.Session.SNwkSIntKey.Key, dev.Session.SNwkSIntKey.KEKLabel) + if err != nil { + logger.WithField("kek_label", dev.Session.SNwkSIntKey.KEKLabel).WithError(err).Error("Failed to unwrap SNwkSIntKey") + return nil, nil, err + } + copy(key[:], b) + } else { + copy(key[:], dev.Session.SNwkSIntKey.Key[:]) } - copy(key[:], dev.Session.SNwkSIntKey.Key[:]) var mic [4]byte if dev.MACState.LoRaWANVersion.Compare(ttnpb.MAC_V1_1) < 0 { @@ -604,11 +613,9 @@ func (ns *NetworkServer) processDownlinkTask(ctx context.Context) error { if req.Rx2DataRateIndex < minDR { minDR = req.Rx2DataRateIndex } - b, appDown, err := generateDownlink(ctx, dev, + b, appDown, err := ns.generateDownlink(ctx, dev, band.DataRates[minDR].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), maxUpLength, - ns.FrequencyPlans, - ns.defaultMACSettings, ) if err != nil { return nil, nil, err @@ -659,11 +666,9 @@ func (ns *NetworkServer) processDownlinkTask(ctx context.Context) error { // we need to create a deep copy for the first call. devCopy := deepcopy.Copy(dev).(*ttnpb.EndDevice) - b, appDown, err := generateDownlink(ctx, dev, + b, appDown, err := ns.generateDownlink(ctx, dev, band.DataRates[req.Rx1DataRateIndex].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), maxUpLength, - ns.FrequencyPlans, - ns.defaultMACSettings, ) if err != nil { if errors.Resemble(err, errScheduleTooSoon) { @@ -754,11 +759,9 @@ func (ns *NetworkServer) processDownlinkTask(ctx context.Context) error { Rx2Frequency: dev.MACState.CurrentParameters.Rx2Frequency, } - b, appDown, err := generateDownlink(ctx, dev, + b, appDown, err := ns.generateDownlink(ctx, dev, band.DataRates[req.Rx2DataRateIndex].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), maxUpLength, - ns.FrequencyPlans, - ns.defaultMACSettings, ) if err != nil { return nil, nil, err diff --git a/pkg/networkserver/downlink_internal_test.go b/pkg/networkserver/downlink_internal_test.go index ee346fd970..b9085cb851 100644 --- a/pkg/networkserver/downlink_internal_test.go +++ b/pkg/networkserver/downlink_internal_test.go @@ -305,11 +305,9 @@ func TestProcessDownlinkTask(t *testing.T) { fp := test.Must(ns.FrequencyPlans.GetByID(test.EUFrequencyPlanID)).(*frequencyplans.FrequencyPlan) rx1DRIdx := test.Must(band.Rx1DataRate(ttnpb.DATA_RATE_0, 2, false)).(ttnpb.DataRateIndex) rx1Freq := channels[int(test.Must(band.Rx1Channel(3)).(uint8))].DownlinkFrequency - payload, _, err := GenerateDownlink(ctx, CopyEndDevice(pb), + payload, _, err := ns.generateDownlink(ctx, CopyEndDevice(pb), band.DataRates[ttnpb.DATA_RATE_1].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), - ns.FrequencyPlans, - ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx2 payload: %s", err) @@ -381,11 +379,9 @@ func TestProcessDownlinkTask(t *testing.T) { if rx1DRIdx < drIdx { drIdx = rx1DRIdx } - payload, _, err := GenerateDownlink(ctx, CopyEndDevice(pb), + payload, _, err := ns.generateDownlink(ctx, CopyEndDevice(pb), band.DataRates[drIdx].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), - ns.FrequencyPlans, - ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx2 payload: %s", err) @@ -733,11 +729,9 @@ func TestProcessDownlinkTask(t *testing.T) { fp := test.Must(ns.FrequencyPlans.GetByID(test.EUFrequencyPlanID)).(*frequencyplans.FrequencyPlan) rx1DRIdx := test.Must(band.Rx1DataRate(ttnpb.DATA_RATE_0, 2, false)).(ttnpb.DataRateIndex) rx1Freq := channels[int(test.Must(band.Rx1Channel(3)).(uint8))].DownlinkFrequency - payload, _, err := GenerateDownlink(ctx, CopyEndDevice(pb), + payload, _, err := ns.generateDownlink(ctx, CopyEndDevice(pb), band.DataRates[rx1DRIdx].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), - ns.FrequencyPlans, - ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx1 payload: %s", err) @@ -805,11 +799,9 @@ func TestProcessDownlinkTask(t *testing.T) { fp := test.Must(ns.FrequencyPlans.GetByID(test.EUFrequencyPlanID)).(*frequencyplans.FrequencyPlan) rx1DRIdx := test.Must(band.Rx1DataRate(ttnpb.DATA_RATE_0, 2, false)).(ttnpb.DataRateIndex) rx1Freq := channels[int(test.Must(band.Rx1Channel(3)).(uint8))].DownlinkFrequency - payload, _, err := GenerateDownlink(ctx, CopyEndDevice(pb), + payload, _, err := ns.generateDownlink(ctx, CopyEndDevice(pb), band.DataRates[rx1DRIdx].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), - ns.FrequencyPlans, - ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx1 payload: %s", err) @@ -1148,11 +1140,9 @@ func TestProcessDownlinkTask(t *testing.T) { t.Fatal("Invalid context") } fp := test.Must(ns.FrequencyPlans.GetByID(test.EUFrequencyPlanID)).(*frequencyplans.FrequencyPlan) - rx2Payload, _, err := GenerateDownlink(ctx, CopyEndDevice(pb), + rx2Payload, _, err := ns.generateDownlink(ctx, CopyEndDevice(pb), band.DataRates[ttnpb.DATA_RATE_1].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), - ns.FrequencyPlans, - ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx2 payload: %s", err) @@ -1222,20 +1212,16 @@ func TestProcessDownlinkTask(t *testing.T) { fp := test.Must(ns.FrequencyPlans.GetByID(test.EUFrequencyPlanID)).(*frequencyplans.FrequencyPlan) rx1DRIdx := test.Must(band.Rx1DataRate(ttnpb.DATA_RATE_0, 2, false)).(ttnpb.DataRateIndex) rx1Freq := channels[int(test.Must(band.Rx1Channel(3)).(uint8))].DownlinkFrequency - rx1Payload, _, err := GenerateDownlink(ctx, CopyEndDevice(pb), + rx1Payload, _, err := ns.generateDownlink(ctx, CopyEndDevice(pb), band.DataRates[rx1DRIdx].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), - ns.FrequencyPlans, - ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx1 payload: %s", err) } - rx2Payload, _, err := GenerateDownlink(ctx, CopyEndDevice(pb), + rx2Payload, _, err := ns.generateDownlink(ctx, CopyEndDevice(pb), band.DataRates[ttnpb.DATA_RATE_1].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), - ns.FrequencyPlans, - ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx2 payload: %s", err) @@ -1731,11 +1717,9 @@ func TestProcessDownlinkTask(t *testing.T) { t.Fatal("Invalid context") } fp := test.Must(ns.FrequencyPlans.GetByID(test.EUFrequencyPlanID)).(*frequencyplans.FrequencyPlan) - rx2Payload, _, err := GenerateDownlink(ctx, CopyEndDevice(pb), + rx2Payload, _, err := ns.generateDownlink(ctx, CopyEndDevice(pb), band.DataRates[ttnpb.DATA_RATE_1].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), - ns.FrequencyPlans, - ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx2 payload: %s", err) @@ -1808,20 +1792,16 @@ func TestProcessDownlinkTask(t *testing.T) { fp := test.Must(ns.FrequencyPlans.GetByID(test.EUFrequencyPlanID)).(*frequencyplans.FrequencyPlan) rx1DRIdx := test.Must(band.Rx1DataRate(ttnpb.DATA_RATE_0, 2, false)).(ttnpb.DataRateIndex) rx1Freq := channels[int(test.Must(band.Rx1Channel(3)).(uint8))].DownlinkFrequency - rx1Payload, _, err := GenerateDownlink(ctx, CopyEndDevice(pb), + rx1Payload, _, err := ns.generateDownlink(ctx, CopyEndDevice(pb), band.DataRates[rx1DRIdx].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), - ns.FrequencyPlans, - ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx1 payload: %s", err) } - rx2Payload, _, err := GenerateDownlink(ctx, CopyEndDevice(pb), + rx2Payload, _, err := ns.generateDownlink(ctx, CopyEndDevice(pb), band.DataRates[ttnpb.DATA_RATE_1].DefaultMaxSize.PayloadSize(fp.DwellTime.GetDownlinks()), band.DataRates[ttnpb.DATA_RATE_0].DefaultMaxSize.PayloadSize(fp.DwellTime.GetUplinks()), - ns.FrequencyPlans, - ns.defaultMACSettings, ) if !a.So(err, should.BeNil) { t.Fatalf("Failed to generate Rx2 payload: %s", err) @@ -3508,12 +3488,26 @@ func TestGenerateDownlink(t *testing.T) { t.Run(tc.Name, func(t *testing.T) { a := assertions.New(t) + ns := test.Must(New( + component.MustNew(test.GetLogger(t), + &component.Config{}, + ), + &Config{ + DeduplicationWindow: 42, + CooldownWindow: 42, + DownlinkTasks: &MockDownlinkTaskQueue{}, + Devices: &MockDeviceRegistry{}, + DefaultStatusTimePeriodicity: DurationPtr(0), + DefaultStatusCountPeriodicity: func(v uint32) *uint32 { return &v }(0), + }, + )).(*NetworkServer) + ns.FrequencyPlans = frequencyplans.NewStore(test.FrequencyPlansFetcher) + test.Must(nil, ns.Start()) + defer ns.Close() + dev := CopyEndDevice(tc.Device) - b, appDown, err := generateDownlink(tc.Context, dev, math.MaxUint16, math.MaxUint16, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{ - StatusTimePeriodicity: DurationPtr(0), - StatusCountPeriodicity: &pbtypes.UInt32Value{Value: 0}, - }) + b, appDown, err := ns.generateDownlink(tc.Context, dev, math.MaxUint16, math.MaxUint16) if tc.Error != nil && !a.So(err, should.EqualErrorOrDefinition, tc.Error) || tc.Error == nil && !a.So(err, should.BeNil) { t.FailNow() diff --git a/pkg/networkserver/grpc_gsns.go b/pkg/networkserver/grpc_gsns.go index c1d7f59071..bdf2914b76 100644 --- a/pkg/networkserver/grpc_gsns.go +++ b/pkg/networkserver/grpc_gsns.go @@ -82,14 +82,14 @@ func (ns *NetworkServer) matchDevice(ctx context.Context, up *ttnpb.UplinkMessag if len(up.RawPayload) < 4 { return nil, nil, errRawPayloadTooShort } - b := up.RawPayload[:len(up.RawPayload)-4] + macPayloadBytes := up.RawPayload[:len(up.RawPayload)-4] pld := up.Payload.GetMACPayload() logger := log.FromContext(ctx).WithFields(log.Fields( "dev_addr", pld.DevAddr, "uplink_f_cnt", pld.FCnt, - "payload_length", len(b), + "payload_length", len(macPayloadBytes), )) type device struct { @@ -274,16 +274,21 @@ outer: } if dev.matchedSession.FNwkSIntKey == nil || len(dev.matchedSession.FNwkSIntKey.Key) == 0 { - logger.Warn("Device missing FNwkSIntKey in registry") + logger.Warn("Device missing FNwkSIntKey in registry, skipping...") continue } var fNwkSIntKey types.AES128Key if dev.matchedSession.FNwkSIntKey.KEKLabel != "" { - // TODO: https://github.com/TheThingsNetwork/lorawan-stack/issues/5 - panic("unsupported") + b, err := ns.Component.KeyVault.Unwrap(dev.matchedSession.FNwkSIntKey.Key, dev.matchedSession.FNwkSIntKey.KEKLabel) + if err != nil { + logger.WithField("kek_label", dev.matchedSession.FNwkSIntKey.KEKLabel).WithError(err).Error("Failed to unwrap FNwkSIntKey, skipping...") + continue + } + copy(fNwkSIntKey[:], b) + } else { + copy(fNwkSIntKey[:], dev.matchedSession.FNwkSIntKey.Key[:]) } - copy(fNwkSIntKey[:], dev.matchedSession.FNwkSIntKey.Key[:]) var computedMIC [4]byte var err error @@ -292,20 +297,25 @@ outer: fNwkSIntKey, pld.DevAddr, dev.fCnt, - b, + macPayloadBytes, ) } else { if dev.matchedSession.SNwkSIntKey == nil || len(dev.matchedSession.SNwkSIntKey.Key) == 0 { - logger.Warn("Device missing SNwkSIntKey in registry") + logger.Warn("Device missing SNwkSIntKey in registry, skipping...") continue } var sNwkSIntKey types.AES128Key if dev.matchedSession.SNwkSIntKey.KEKLabel != "" { - // TODO: https://github.com/TheThingsNetwork/lorawan-stack/issues/5 - panic("unsupported") + b, err := ns.Component.KeyVault.Unwrap(dev.matchedSession.SNwkSIntKey.Key, dev.matchedSession.SNwkSIntKey.KEKLabel) + if err != nil { + logger.WithField("kek_label", dev.matchedSession.SNwkSIntKey.KEKLabel).WithError(err).Error("Failed to unwrap SNwkSIntKey, skipping...") + continue + } + copy(sNwkSIntKey[:], b) + } else { + copy(sNwkSIntKey[:], dev.matchedSession.SNwkSIntKey.Key[:]) } - copy(sNwkSIntKey[:], dev.matchedSession.SNwkSIntKey.Key[:]) var confFCnt uint32 if pld.Ack { @@ -332,7 +342,7 @@ outer: chIdx, pld.DevAddr, dev.fCnt, - b, + macPayloadBytes, ) } if err != nil { @@ -426,10 +436,15 @@ func (ns *NetworkServer) handleUplink(ctx context.Context, up *ttnpb.UplinkMessa var key types.AES128Key if ses.NwkSEncKey.KEKLabel != "" { - // TODO: https://github.com/TheThingsNetwork/lorawan-stack/issues/5 - panic("unsupported") + b, err := ns.Component.KeyVault.Unwrap(ses.NwkSEncKey.Key, ses.NwkSEncKey.KEKLabel) + if err != nil { + logger.WithField("kek_label", ses.NwkSEncKey.KEKLabel).WithError(err).Error("Failed to unwrap NwkSEncKey") + return err + } + copy(key[:], b) + } else { + copy(key[:], ses.NwkSEncKey.Key[:]) } - copy(key[:], ses.NwkSEncKey.Key[:]) mac, err = crypto.DecryptUplink(key, pld.DevAddr, pld.FCnt, mac) if err != nil { diff --git a/pkg/networkserver/networkserver_util_test.go b/pkg/networkserver/networkserver_util_test.go index 9698c367ad..81e28d5d3e 100644 --- a/pkg/networkserver/networkserver_util_test.go +++ b/pkg/networkserver/networkserver_util_test.go @@ -30,9 +30,8 @@ const ( ) var ( - ResetMACState = resetMACState - GenerateDownlink = generateDownlink - TimePtr = timePtr + ResetMACState = resetMACState + TimePtr = timePtr ErrNoDownlink = errNoDownlink ErrDeviceNotFound = errDeviceNotFound From c99a7e09402be6504d7481dbe421a6d147ecad80 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 15 Feb 2019 14:00:48 +0100 Subject: [PATCH 22/40] cli: Remove redundant/non-existent device paths --- cmd/ttn-lw-cli/commands/end_devices.go | 6 ------ cmd/ttn-lw-cli/commands/end_devices_split.go | 12 ++---------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/cmd/ttn-lw-cli/commands/end_devices.go b/cmd/ttn-lw-cli/commands/end_devices.go index 01a236b0ce..f7d609c26e 100644 --- a/cmd/ttn-lw-cli/commands/end_devices.go +++ b/cmd/ttn-lw-cli/commands/end_devices.go @@ -237,16 +237,10 @@ var ( device.NetworkServerAddress = config.NetworkServerAddress device.ApplicationServerAddress = config.ApplicationServerAddress device.JoinServerAddress = config.JoinServerAddress - device.Uses32BitFCnt = true paths = append(paths, "application_server_address", "join_server_address", "network_server_address", - "resets_f_cnt", - "resets_join_nonces", - "supports_class_b", - "supports_class_c", - "uses_32_bit_f_cnt", ) } diff --git a/cmd/ttn-lw-cli/commands/end_devices_split.go b/cmd/ttn-lw-cli/commands/end_devices_split.go index 1cb5bfb24a..af4f146c69 100644 --- a/cmd/ttn-lw-cli/commands/end_devices_split.go +++ b/cmd/ttn-lw-cli/commands/end_devices_split.go @@ -68,8 +68,6 @@ func getEndDevicePathFromNS(pathParts ...string) bool { switch pathParts[0] { case "battery_percentage", - "default_class", - "default_mac_parameters", "downlink_margin", "frequency_plan_id", "last_dev_status_received_at", @@ -82,12 +80,10 @@ func getEndDevicePathFromNS(pathParts ...string) bool { "power_state", "recent_downlinks", "recent_uplinks", - "resets_f_cnt", "resets_join_nonces", "supports_class_b", "supports_class_c", - "supports_join", - "uses_32_bit_f_cnt": + "supports_join": return true case "session": if len(pathParts) == 1 { @@ -122,20 +118,16 @@ func getEndDevicePathFromNS(pathParts ...string) bool { func setEndDevicePathToNS(pathParts ...string) bool { switch pathParts[0] { case - "default_class", - "default_mac_parameters", "frequency_plan_id", "lorawan_phy_version", "lorawan_version", "mac_settings", "max_frequency", "min_frequency", - "resets_f_cnt", "resets_join_nonces", "supports_class_b", "supports_class_c", - "supports_join", - "uses_32_bit_f_cnt": + "supports_join": return true case "session": if len(pathParts) == 1 { From 9c77fbc4216f48725579cea8c98f8064f2dcfc11 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 15 Feb 2019 14:18:07 +0100 Subject: [PATCH 23/40] util: Fix NetID handling in config package --- pkg/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 56eef434c2..4d14f548d3 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -479,7 +479,7 @@ func (m *Manager) setDefaults(prefix string, flags *pflag.FlagSet, config interf flags.StringP(name, shorthand, str, description) case types.NetID: - str := fmt.Sprintf("%X", val) + str := val.String() m.viper.SetDefault(name, str) flags.StringP(name, shorthand, str, description) From a5d4839a11103bfeb92b41e24e7f2cd49919c050 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Fri, 15 Feb 2019 14:22:15 +0100 Subject: [PATCH 24/40] ns: Fix class C downlinks --- pkg/networkserver/downlink.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/networkserver/downlink.go b/pkg/networkserver/downlink.go index 20cad79fe6..2686ccf4dc 100644 --- a/pkg/networkserver/downlink.go +++ b/pkg/networkserver/downlink.go @@ -259,6 +259,7 @@ outer: break case dev.MACState.DeviceClass == ttnpb.CLASS_C && + dev.MACState.LastConfirmedDownlinkAt != nil && dev.MACState.LastConfirmedDownlinkAt.Add(deviceClassCTimeout(dev, ns.defaultMACSettings)).After(time.Now()): return nil, nil, errScheduleTooSoon From ed594777e21209980af2f50926d3262f2aface1a Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 19 Feb 2019 13:51:31 +0100 Subject: [PATCH 25/40] api: Add documentation to MACSettings fields --- api/api.md | 40 +++++++++---------- api/api.swagger.json | 40 +++++++++---------- api/end_device.proto | 31 +++++++++------ pkg/ttnpb/end_device.pb.go | 81 +++++++++++++++++++++----------------- 4 files changed, 105 insertions(+), 87 deletions(-) diff --git a/api/api.md b/api/api.md index c7c4335903..38b1aa1680 100644 --- a/api/api.md +++ b/api/api.md @@ -1782,27 +1782,27 @@ This is used internally by the Network Server and is read only. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| class_b_timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | Maximum delay for the device to answer a MAC request or a confirmed downlink frame. Must be set if the device supports class B. | -| ping_slot_periodicity | [MACSettings.PingSlotPeriodValue](#ttn.lorawan.v3.MACSettings.PingSlotPeriodValue) | | Periodicity of the class B ping slot. Must be set if the device supports class B. | -| ping_slot_data_rate_index | [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) | | Data rate index of the class B ping slot. Must be set if the device supports class B. | -| ping_slot_frequency | [uint64](#uint64) | | Frequency of the class B ping slot (Hz). Must be set if the device supports class B. | -| class_c_timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | Maximum delay for the device to answer a MAC request or a confirmed downlink frame. Must be set if the device supports class C. | -| rx1_delay | [MACSettings.RxDelayValue](#ttn.lorawan.v3.MACSettings.RxDelayValue) | | Class A Rx1 delay. Must be set if the device is ABP. | -| rx1_data_rate_offset | [google.protobuf.UInt32Value](#google.protobuf.UInt32Value) | | Rx1 data rate offset. Must be set if the device is ABP. | -| rx2_data_rate_index | [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) | | Data rate index for Rx2. Must be set if the device is ABP. | -| rx2_frequency | [uint64](#uint64) | | Frequency for Rx2 (Hz). Must be set if the device is ABP. | -| factory_preset_frequencies | [uint64](#uint64) | repeated | List of factory-preset frequencies. Must be set if the device is ABP. | +| class_b_timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | Maximum delay for the device to answer a MAC request or a confirmed downlink frame. If unset, the default value from Network Server configuration will be used. | +| ping_slot_periodicity | [MACSettings.PingSlotPeriodValue](#ttn.lorawan.v3.MACSettings.PingSlotPeriodValue) | | Periodicity of the class B ping slot. If unset, the default value from Network Server configuration will be used. | +| ping_slot_data_rate_index | [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) | | Data rate index of the class B ping slot. If unset, the default value from Network Server configuration will be used. | +| ping_slot_frequency | [uint64](#uint64) | | Frequency of the class B ping slot (Hz). If unset, the default value from Network Server configuration will be used. | +| class_c_timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | Maximum delay for the device to answer a MAC request or a confirmed downlink frame. If unset, the default value from Network Server configuration will be used. | +| rx1_delay | [MACSettings.RxDelayValue](#ttn.lorawan.v3.MACSettings.RxDelayValue) | | Class A Rx1 delay. If unset, the default value from Network Server configuration or regional parameters specification will be used. | +| rx1_data_rate_offset | [google.protobuf.UInt32Value](#google.protobuf.UInt32Value) | | Rx1 data rate offset. If unset, the default value from Network Server configuration will be used. | +| rx2_data_rate_index | [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) | | Data rate index for Rx2. If unset, the default value from Network Server configuration or regional parameters specification will be used. | +| rx2_frequency | [uint64](#uint64) | | Frequency for Rx2 (Hz). If unset, the default value from Network Server configuration or regional parameters specification will be used. | +| factory_preset_frequencies | [uint64](#uint64) | repeated | List of factory-preset frequencies. If unset, the default value from Network Server configuration or regional parameters specification will be used. | | max_duty_cycle | [MACSettings.AggregatedDutyCycleValue](#ttn.lorawan.v3.MACSettings.AggregatedDutyCycleValue) | | Maximum uplink duty cycle (of all channels). | -| supports_32_bit_f_cnt | [google.protobuf.BoolValue](#google.protobuf.BoolValue) | | Whether the device supports 32-bit frame counters. Must be set if the device MAC version is 1.0. | -| use_adr | [google.protobuf.BoolValue](#google.protobuf.BoolValue) | | Whether the Network Server should use ADR for the device. | -| adr_margin | [google.protobuf.FloatValue](#google.protobuf.FloatValue) | | The ADR margin tells the network server how much margin it should add in ADR requests. A bigger margin is less efficient, but gives a better chance of successful reception. | -| resets_f_cnt | [google.protobuf.BoolValue](#google.protobuf.BoolValue) | | Whether the device resets the frame counters (not LoRaWAN compliant). | -| status_time_periodicity | [google.protobuf.Duration](#google.protobuf.Duration) | | The interval after which a DevStatusReq MACCommand shall be sent. | -| status_count_periodicity | [google.protobuf.UInt32Value](#google.protobuf.UInt32Value) | | Number of uplink messages after which a DevStatusReq MACCommand shall be sent. | -| desired_rx1_delay | [MACSettings.RxDelayValue](#ttn.lorawan.v3.MACSettings.RxDelayValue) | | The Rx1 delay Network Server should configure device to use via MAC commands or Join-Accept. | -| desired_rx1_data_rate_offset | [google.protobuf.UInt32Value](#google.protobuf.UInt32Value) | | The Rx1 data rate offset Network Server should configure device to use via MAC commands or Join-Accept. | -| desired_rx2_data_rate_index | [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) | | The Rx2 data rate index Network Server should configure device to use via MAC commands or Join-Accept. | -| desired_rx2_frequency | [uint64](#uint64) | | The Rx2 frequency index Network Server should configure device to use via MAC commands. | +| supports_32_bit_f_cnt | [google.protobuf.BoolValue](#google.protobuf.BoolValue) | | Whether the device supports 32-bit frame counters. If unset, the default value from Network Server configuration will be used. | +| use_adr | [google.protobuf.BoolValue](#google.protobuf.BoolValue) | | Whether the Network Server should use ADR for the device. If unset, the default value from Network Server configuration will be used. | +| adr_margin | [google.protobuf.FloatValue](#google.protobuf.FloatValue) | | The ADR margin tells the network server how much margin it should add in ADR requests. A bigger margin is less efficient, but gives a better chance of successful reception. If unset, the default value from Network Server configuration will be used. | +| resets_f_cnt | [google.protobuf.BoolValue](#google.protobuf.BoolValue) | | Whether the device resets the frame counters (not LoRaWAN compliant). If unset, the default value from Network Server configuration will be used. | +| status_time_periodicity | [google.protobuf.Duration](#google.protobuf.Duration) | | The interval after which a DevStatusReq MACCommand shall be sent. If unset, the default value from Network Server configuration will be used. | +| status_count_periodicity | [google.protobuf.UInt32Value](#google.protobuf.UInt32Value) | | Number of uplink messages after which a DevStatusReq MACCommand shall be sent. If unset, the default value from Network Server configuration will be used. | +| desired_rx1_delay | [MACSettings.RxDelayValue](#ttn.lorawan.v3.MACSettings.RxDelayValue) | | The Rx1 delay Network Server should configure device to use via MAC commands or Join-Accept. If unset, the default value from Network Server configuration or regional parameters specification will be used. | +| desired_rx1_data_rate_offset | [google.protobuf.UInt32Value](#google.protobuf.UInt32Value) | | The Rx1 data rate offset Network Server should configure device to use via MAC commands or Join-Accept. If unset, the default value from Network Server configuration will be used. | +| desired_rx2_data_rate_index | [MACSettings.DataRateIndexValue](#ttn.lorawan.v3.MACSettings.DataRateIndexValue) | | The Rx2 data rate index Network Server should configure device to use via MAC commands or Join-Accept. If unset, the default value from frequency plan, Network Server configuration or regional parameters specification will be used. | +| desired_rx2_frequency | [uint64](#uint64) | | The Rx2 frequency index Network Server should configure device to use via MAC commands. If unset, the default value from frequency plan, Network Server configuration or regional parameters specification will be used. | diff --git a/api/api.swagger.json b/api/api.swagger.json index 9a0b9b3f3e..7b3f751330 100644 --- a/api/api.swagger.json +++ b/api/api.swagger.json @@ -7433,42 +7433,42 @@ "properties": { "class_b_timeout": { "type": "string", - "description": "Maximum delay for the device to answer a MAC request or a confirmed downlink frame.\nMust be set if the device supports class B." + "description": "Maximum delay for the device to answer a MAC request or a confirmed downlink frame.\nIf unset, the default value from Network Server configuration will be used." }, "ping_slot_periodicity": { "$ref": "#/definitions/MACSettingsPingSlotPeriodValue", - "description": "Periodicity of the class B ping slot.\nMust be set if the device supports class B." + "description": "Periodicity of the class B ping slot.\nIf unset, the default value from Network Server configuration will be used." }, "ping_slot_data_rate_index": { "$ref": "#/definitions/MACSettingsDataRateIndexValue", - "description": "Data rate index of the class B ping slot.\nMust be set if the device supports class B." + "description": "Data rate index of the class B ping slot.\nIf unset, the default value from Network Server configuration will be used." }, "ping_slot_frequency": { "type": "string", "format": "uint64", - "description": "Frequency of the class B ping slot (Hz).\nMust be set if the device supports class B." + "description": "Frequency of the class B ping slot (Hz).\nIf unset, the default value from Network Server configuration will be used." }, "class_c_timeout": { "type": "string", - "description": "Maximum delay for the device to answer a MAC request or a confirmed downlink frame.\nMust be set if the device supports class C." + "description": "Maximum delay for the device to answer a MAC request or a confirmed downlink frame.\nIf unset, the default value from Network Server configuration will be used." }, "rx1_delay": { "$ref": "#/definitions/MACSettingsRxDelayValue", - "description": "Class A Rx1 delay.\nMust be set if the device is ABP." + "description": "Class A Rx1 delay.\nIf unset, the default value from Network Server configuration or regional parameters specification will be used." }, "rx1_data_rate_offset": { "type": "integer", "format": "int64", - "description": "Rx1 data rate offset.\nMust be set if the device is ABP." + "description": "Rx1 data rate offset.\nIf unset, the default value from Network Server configuration will be used." }, "rx2_data_rate_index": { "$ref": "#/definitions/MACSettingsDataRateIndexValue", - "description": "Data rate index for Rx2.\nMust be set if the device is ABP." + "description": "Data rate index for Rx2.\nIf unset, the default value from Network Server configuration or regional parameters specification will be used." }, "rx2_frequency": { "type": "string", "format": "uint64", - "description": "Frequency for Rx2 (Hz).\nMust be set if the device is ABP." + "description": "Frequency for Rx2 (Hz).\nIf unset, the default value from Network Server configuration or regional parameters specification will be used." }, "factory_preset_frequencies": { "type": "array", @@ -7476,7 +7476,7 @@ "type": "string", "format": "uint64" }, - "description": "List of factory-preset frequencies.\nMust be set if the device is ABP." + "description": "List of factory-preset frequencies.\nIf unset, the default value from Network Server configuration or regional parameters specification will be used." }, "max_duty_cycle": { "$ref": "#/definitions/MACSettingsAggregatedDutyCycleValue", @@ -7485,49 +7485,49 @@ "supports_32_bit_f_cnt": { "type": "boolean", "format": "boolean", - "description": "Whether the device supports 32-bit frame counters.\nMust be set if the device MAC version is 1.0." + "description": "Whether the device supports 32-bit frame counters.\nIf unset, the default value from Network Server configuration will be used." }, "use_adr": { "type": "boolean", "format": "boolean", - "description": "Whether the Network Server should use ADR for the device." + "description": "Whether the Network Server should use ADR for the device.\nIf unset, the default value from Network Server configuration will be used." }, "adr_margin": { "type": "number", "format": "float", - "description": "The ADR margin tells the network server how much margin it should add in ADR requests.\nA bigger margin is less efficient, but gives a better chance of successful reception." + "description": "The ADR margin tells the network server how much margin it should add in ADR requests.\nA bigger margin is less efficient, but gives a better chance of successful reception.\nIf unset, the default value from Network Server configuration will be used." }, "resets_f_cnt": { "type": "boolean", "format": "boolean", - "description": "Whether the device resets the frame counters (not LoRaWAN compliant)." + "description": "Whether the device resets the frame counters (not LoRaWAN compliant).\nIf unset, the default value from Network Server configuration will be used." }, "status_time_periodicity": { "type": "string", - "description": "The interval after which a DevStatusReq MACCommand shall be sent." + "description": "The interval after which a DevStatusReq MACCommand shall be sent.\nIf unset, the default value from Network Server configuration will be used." }, "status_count_periodicity": { "type": "integer", "format": "int64", - "description": "Number of uplink messages after which a DevStatusReq MACCommand shall be sent." + "description": "Number of uplink messages after which a DevStatusReq MACCommand shall be sent.\nIf unset, the default value from Network Server configuration will be used." }, "desired_rx1_delay": { "$ref": "#/definitions/MACSettingsRxDelayValue", - "description": "The Rx1 delay Network Server should configure device to use via MAC commands or Join-Accept." + "description": "The Rx1 delay Network Server should configure device to use via MAC commands or Join-Accept.\nIf unset, the default value from Network Server configuration or regional parameters specification will be used." }, "desired_rx1_data_rate_offset": { "type": "integer", "format": "int64", - "description": "The Rx1 data rate offset Network Server should configure device to use via MAC commands or Join-Accept." + "description": "The Rx1 data rate offset Network Server should configure device to use via MAC commands or Join-Accept.\nIf unset, the default value from Network Server configuration will be used." }, "desired_rx2_data_rate_index": { "$ref": "#/definitions/MACSettingsDataRateIndexValue", - "description": "The Rx2 data rate index Network Server should configure device to use via MAC commands or Join-Accept." + "description": "The Rx2 data rate index Network Server should configure device to use via MAC commands or Join-Accept.\nIf unset, the default value from frequency plan, Network Server configuration or regional parameters specification will be used." }, "desired_rx2_frequency": { "type": "string", "format": "uint64", - "description": "The Rx2 frequency index Network Server should configure device to use via MAC commands." + "description": "The Rx2 frequency index Network Server should configure device to use via MAC commands.\nIf unset, the default value from frequency plan, Network Server configuration or regional parameters specification will be used." } } }, diff --git a/api/end_device.proto b/api/end_device.proto index db8258e91f..7b0d27a423 100644 --- a/api/end_device.proto +++ b/api/end_device.proto @@ -187,64 +187,73 @@ message MACSettings { } // Maximum delay for the device to answer a MAC request or a confirmed downlink frame. - // Must be set if the device supports class B. + // If unset, the default value from Network Server configuration will be used. google.protobuf.Duration class_b_timeout = 1 [(gogoproto.stdduration) = true]; // Periodicity of the class B ping slot. - // Must be set if the device supports class B. + // If unset, the default value from Network Server configuration will be used. PingSlotPeriodValue ping_slot_periodicity = 2; // Data rate index of the class B ping slot. - // Must be set if the device supports class B. + // If unset, the default value from Network Server configuration will be used. DataRateIndexValue ping_slot_data_rate_index = 3; // Frequency of the class B ping slot (Hz). - // Must be set if the device supports class B. + // If unset, the default value from Network Server configuration will be used. uint64 ping_slot_frequency = 4; // Maximum delay for the device to answer a MAC request or a confirmed downlink frame. - // Must be set if the device supports class C. + // If unset, the default value from Network Server configuration will be used. google.protobuf.Duration class_c_timeout = 5 [(gogoproto.stdduration) = true]; // Class A Rx1 delay. - // Must be set if the device is ABP. + // If unset, the default value from Network Server configuration or regional parameters specification will be used. RxDelayValue rx1_delay = 6; // Rx1 data rate offset. - // Must be set if the device is ABP. + // If unset, the default value from Network Server configuration will be used. google.protobuf.UInt32Value rx1_data_rate_offset = 7; // Data rate index for Rx2. - // Must be set if the device is ABP. + // If unset, the default value from Network Server configuration or regional parameters specification will be used. DataRateIndexValue rx2_data_rate_index = 8; // Frequency for Rx2 (Hz). - // Must be set if the device is ABP. + // If unset, the default value from Network Server configuration or regional parameters specification will be used. uint64 rx2_frequency = 9; // List of factory-preset frequencies. - // Must be set if the device is ABP. + // If unset, the default value from Network Server configuration or regional parameters specification will be used. repeated uint64 factory_preset_frequencies = 10; // Maximum uplink duty cycle (of all channels). AggregatedDutyCycleValue max_duty_cycle = 11; // Whether the device supports 32-bit frame counters. - // Must be set if the device MAC version is 1.0. + // If unset, the default value from Network Server configuration will be used. google.protobuf.BoolValue supports_32_bit_f_cnt = 12 [(gogoproto.customname) = "Supports32BitFCnt"]; // Whether the Network Server should use ADR for the device. + // If unset, the default value from Network Server configuration will be used. google.protobuf.BoolValue use_adr = 13 [(gogoproto.customname) = "UseADR"]; // The ADR margin tells the network server how much margin it should add in ADR requests. // A bigger margin is less efficient, but gives a better chance of successful reception. + // If unset, the default value from Network Server configuration will be used. google.protobuf.FloatValue adr_margin = 14 [(gogoproto.customname) = "ADRMargin"]; // Whether the device resets the frame counters (not LoRaWAN compliant). + // If unset, the default value from Network Server configuration will be used. google.protobuf.BoolValue resets_f_cnt = 15; // The interval after which a DevStatusReq MACCommand shall be sent. + // If unset, the default value from Network Server configuration will be used. google.protobuf.Duration status_time_periodicity = 16 [(gogoproto.stdduration) = true]; // Number of uplink messages after which a DevStatusReq MACCommand shall be sent. + // If unset, the default value from Network Server configuration will be used. google.protobuf.UInt32Value status_count_periodicity = 17; // The Rx1 delay Network Server should configure device to use via MAC commands or Join-Accept. + // If unset, the default value from Network Server configuration or regional parameters specification will be used. RxDelayValue desired_rx1_delay = 18; // The Rx1 data rate offset Network Server should configure device to use via MAC commands or Join-Accept. + // If unset, the default value from Network Server configuration will be used. google.protobuf.UInt32Value desired_rx1_data_rate_offset = 19; // The Rx2 data rate index Network Server should configure device to use via MAC commands or Join-Accept. + // If unset, the default value from frequency plan, Network Server configuration or regional parameters specification will be used. DataRateIndexValue desired_rx2_data_rate_index = 20; // The Rx2 frequency index Network Server should configure device to use via MAC commands. + // If unset, the default value from frequency plan, Network Server configuration or regional parameters specification will be used. uint64 desired_rx2_frequency = 21; } diff --git a/pkg/ttnpb/end_device.pb.go b/pkg/ttnpb/end_device.pb.go index a5c4aa0481..1c7018c916 100644 --- a/pkg/ttnpb/end_device.pb.go +++ b/pkg/ttnpb/end_device.pb.go @@ -62,7 +62,7 @@ var PowerState_value = map[string]int32{ } func (PowerState) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{0} + return fileDescriptor_end_device_7c7976812d2926f8, []int{0} } type Session struct { @@ -87,7 +87,7 @@ type Session struct { func (m *Session) Reset() { *m = Session{} } func (*Session) ProtoMessage() {} func (*Session) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{0} + return fileDescriptor_end_device_7c7976812d2926f8, []int{0} } func (m *Session) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -199,7 +199,7 @@ type MACParameters struct { func (m *MACParameters) Reset() { *m = MACParameters{} } func (*MACParameters) ProtoMessage() {} func (*MACParameters) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{1} + return fileDescriptor_end_device_7c7976812d2926f8, []int{1} } func (m *MACParameters) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -379,7 +379,7 @@ type MACParameters_Channel struct { func (m *MACParameters_Channel) Reset() { *m = MACParameters_Channel{} } func (*MACParameters_Channel) ProtoMessage() {} func (*MACParameters_Channel) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{1, 0} + return fileDescriptor_end_device_7c7976812d2926f8, []int{1, 0} } func (m *MACParameters_Channel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -456,7 +456,7 @@ type EndDeviceBrand struct { func (m *EndDeviceBrand) Reset() { *m = EndDeviceBrand{} } func (*EndDeviceBrand) ProtoMessage() {} func (*EndDeviceBrand) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{2} + return fileDescriptor_end_device_7c7976812d2926f8, []int{2} } func (m *EndDeviceBrand) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -524,7 +524,7 @@ type EndDeviceModel struct { func (m *EndDeviceModel) Reset() { *m = EndDeviceModel{} } func (*EndDeviceModel) ProtoMessage() {} func (*EndDeviceModel) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{3} + return fileDescriptor_end_device_7c7976812d2926f8, []int{3} } func (m *EndDeviceModel) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -587,7 +587,7 @@ type EndDeviceVersionIdentifiers struct { func (m *EndDeviceVersionIdentifiers) Reset() { *m = EndDeviceVersionIdentifiers{} } func (*EndDeviceVersionIdentifiers) ProtoMessage() {} func (*EndDeviceVersionIdentifiers) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{4} + return fileDescriptor_end_device_7c7976812d2926f8, []int{4} } func (m *EndDeviceVersionIdentifiers) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -681,7 +681,7 @@ type EndDeviceVersion struct { func (m *EndDeviceVersion) Reset() { *m = EndDeviceVersion{} } func (*EndDeviceVersion) ProtoMessage() {} func (*EndDeviceVersion) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{5} + return fileDescriptor_end_device_7c7976812d2926f8, []int{5} } func (m *EndDeviceVersion) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -803,58 +803,67 @@ func (m *EndDeviceVersion) GetDefaultFormatters() MessagePayloadFormatters { type MACSettings struct { // Maximum delay for the device to answer a MAC request or a confirmed downlink frame. - // Must be set if the device supports class B. + // If unset, the default value from Network Server configuration will be used. ClassBTimeout *time.Duration `protobuf:"bytes,1,opt,name=class_b_timeout,json=classBTimeout,proto3,stdduration" json:"class_b_timeout,omitempty"` // Periodicity of the class B ping slot. - // Must be set if the device supports class B. + // If unset, the default value from Network Server configuration will be used. PingSlotPeriodicity *MACSettings_PingSlotPeriodValue `protobuf:"bytes,2,opt,name=ping_slot_periodicity,json=pingSlotPeriodicity,proto3" json:"ping_slot_periodicity,omitempty"` // Data rate index of the class B ping slot. - // Must be set if the device supports class B. + // If unset, the default value from Network Server configuration will be used. PingSlotDataRateIndex *MACSettings_DataRateIndexValue `protobuf:"bytes,3,opt,name=ping_slot_data_rate_index,json=pingSlotDataRateIndex,proto3" json:"ping_slot_data_rate_index,omitempty"` // Frequency of the class B ping slot (Hz). - // Must be set if the device supports class B. + // If unset, the default value from Network Server configuration will be used. PingSlotFrequency uint64 `protobuf:"varint,4,opt,name=ping_slot_frequency,json=pingSlotFrequency,proto3" json:"ping_slot_frequency,omitempty"` // Maximum delay for the device to answer a MAC request or a confirmed downlink frame. - // Must be set if the device supports class C. + // If unset, the default value from Network Server configuration will be used. ClassCTimeout *time.Duration `protobuf:"bytes,5,opt,name=class_c_timeout,json=classCTimeout,proto3,stdduration" json:"class_c_timeout,omitempty"` // Class A Rx1 delay. - // Must be set if the device is ABP. + // If unset, the default value from Network Server configuration or regional parameters specification will be used. Rx1Delay *MACSettings_RxDelayValue `protobuf:"bytes,6,opt,name=rx1_delay,json=rx1Delay,proto3" json:"rx1_delay,omitempty"` // Rx1 data rate offset. - // Must be set if the device is ABP. + // If unset, the default value from Network Server configuration will be used. Rx1DataRateOffset *types.UInt32Value `protobuf:"bytes,7,opt,name=rx1_data_rate_offset,json=rx1DataRateOffset,proto3" json:"rx1_data_rate_offset,omitempty"` // Data rate index for Rx2. - // Must be set if the device is ABP. + // If unset, the default value from Network Server configuration or regional parameters specification will be used. Rx2DataRateIndex *MACSettings_DataRateIndexValue `protobuf:"bytes,8,opt,name=rx2_data_rate_index,json=rx2DataRateIndex,proto3" json:"rx2_data_rate_index,omitempty"` // Frequency for Rx2 (Hz). - // Must be set if the device is ABP. + // If unset, the default value from Network Server configuration or regional parameters specification will be used. Rx2Frequency uint64 `protobuf:"varint,9,opt,name=rx2_frequency,json=rx2Frequency,proto3" json:"rx2_frequency,omitempty"` // List of factory-preset frequencies. - // Must be set if the device is ABP. + // If unset, the default value from Network Server configuration or regional parameters specification will be used. FactoryPresetFrequencies []uint64 `protobuf:"varint,10,rep,packed,name=factory_preset_frequencies,json=factoryPresetFrequencies,proto3" json:"factory_preset_frequencies,omitempty"` // Maximum uplink duty cycle (of all channels). MaxDutyCycle *MACSettings_AggregatedDutyCycleValue `protobuf:"bytes,11,opt,name=max_duty_cycle,json=maxDutyCycle,proto3" json:"max_duty_cycle,omitempty"` // Whether the device supports 32-bit frame counters. - // Must be set if the device MAC version is 1.0. + // If unset, the default value from Network Server configuration will be used. Supports32BitFCnt *types.BoolValue `protobuf:"bytes,12,opt,name=supports_32_bit_f_cnt,json=supports32BitFCnt,proto3" json:"supports_32_bit_f_cnt,omitempty"` // Whether the Network Server should use ADR for the device. + // If unset, the default value from Network Server configuration will be used. UseADR *types.BoolValue `protobuf:"bytes,13,opt,name=use_adr,json=useAdr,proto3" json:"use_adr,omitempty"` // The ADR margin tells the network server how much margin it should add in ADR requests. // A bigger margin is less efficient, but gives a better chance of successful reception. + // If unset, the default value from Network Server configuration will be used. ADRMargin *types.FloatValue `protobuf:"bytes,14,opt,name=adr_margin,json=adrMargin,proto3" json:"adr_margin,omitempty"` // Whether the device resets the frame counters (not LoRaWAN compliant). + // If unset, the default value from Network Server configuration will be used. ResetsFCnt *types.BoolValue `protobuf:"bytes,15,opt,name=resets_f_cnt,json=resetsFCnt,proto3" json:"resets_f_cnt,omitempty"` // The interval after which a DevStatusReq MACCommand shall be sent. + // If unset, the default value from Network Server configuration will be used. StatusTimePeriodicity *time.Duration `protobuf:"bytes,16,opt,name=status_time_periodicity,json=statusTimePeriodicity,proto3,stdduration" json:"status_time_periodicity,omitempty"` // Number of uplink messages after which a DevStatusReq MACCommand shall be sent. + // If unset, the default value from Network Server configuration will be used. StatusCountPeriodicity *types.UInt32Value `protobuf:"bytes,17,opt,name=status_count_periodicity,json=statusCountPeriodicity,proto3" json:"status_count_periodicity,omitempty"` // The Rx1 delay Network Server should configure device to use via MAC commands or Join-Accept. + // If unset, the default value from Network Server configuration or regional parameters specification will be used. DesiredRx1Delay *MACSettings_RxDelayValue `protobuf:"bytes,18,opt,name=desired_rx1_delay,json=desiredRx1Delay,proto3" json:"desired_rx1_delay,omitempty"` // The Rx1 data rate offset Network Server should configure device to use via MAC commands or Join-Accept. + // If unset, the default value from Network Server configuration will be used. DesiredRx1DataRateOffset *types.UInt32Value `protobuf:"bytes,19,opt,name=desired_rx1_data_rate_offset,json=desiredRx1DataRateOffset,proto3" json:"desired_rx1_data_rate_offset,omitempty"` // The Rx2 data rate index Network Server should configure device to use via MAC commands or Join-Accept. + // If unset, the default value from frequency plan, Network Server configuration or regional parameters specification will be used. DesiredRx2DataRateIndex *MACSettings_DataRateIndexValue `protobuf:"bytes,20,opt,name=desired_rx2_data_rate_index,json=desiredRx2DataRateIndex,proto3" json:"desired_rx2_data_rate_index,omitempty"` // The Rx2 frequency index Network Server should configure device to use via MAC commands. + // If unset, the default value from frequency plan, Network Server configuration or regional parameters specification will be used. DesiredRx2Frequency uint64 `protobuf:"varint,21,opt,name=desired_rx2_frequency,json=desiredRx2Frequency,proto3" json:"desired_rx2_frequency,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_sizecache int32 `json:"-"` @@ -863,7 +872,7 @@ type MACSettings struct { func (m *MACSettings) Reset() { *m = MACSettings{} } func (*MACSettings) ProtoMessage() {} func (*MACSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{6} + return fileDescriptor_end_device_7c7976812d2926f8, []int{6} } func (m *MACSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1048,7 +1057,7 @@ type MACSettings_DataRateIndexValue struct { func (m *MACSettings_DataRateIndexValue) Reset() { *m = MACSettings_DataRateIndexValue{} } func (*MACSettings_DataRateIndexValue) ProtoMessage() {} func (*MACSettings_DataRateIndexValue) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{6, 0} + return fileDescriptor_end_device_7c7976812d2926f8, []int{6, 0} } func (m *MACSettings_DataRateIndexValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1093,7 +1102,7 @@ type MACSettings_PingSlotPeriodValue struct { func (m *MACSettings_PingSlotPeriodValue) Reset() { *m = MACSettings_PingSlotPeriodValue{} } func (*MACSettings_PingSlotPeriodValue) ProtoMessage() {} func (*MACSettings_PingSlotPeriodValue) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{6, 1} + return fileDescriptor_end_device_7c7976812d2926f8, []int{6, 1} } func (m *MACSettings_PingSlotPeriodValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1138,7 +1147,7 @@ type MACSettings_AggregatedDutyCycleValue struct { func (m *MACSettings_AggregatedDutyCycleValue) Reset() { *m = MACSettings_AggregatedDutyCycleValue{} } func (*MACSettings_AggregatedDutyCycleValue) ProtoMessage() {} func (*MACSettings_AggregatedDutyCycleValue) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{6, 2} + return fileDescriptor_end_device_7c7976812d2926f8, []int{6, 2} } func (m *MACSettings_AggregatedDutyCycleValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1183,7 +1192,7 @@ type MACSettings_RxDelayValue struct { func (m *MACSettings_RxDelayValue) Reset() { *m = MACSettings_RxDelayValue{} } func (*MACSettings_RxDelayValue) ProtoMessage() {} func (*MACSettings_RxDelayValue) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{6, 3} + return fileDescriptor_end_device_7c7976812d2926f8, []int{6, 3} } func (m *MACSettings_RxDelayValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1265,7 +1274,7 @@ type MACState struct { func (m *MACState) Reset() { *m = MACState{} } func (*MACState) ProtoMessage() {} func (*MACState) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{7} + return fileDescriptor_end_device_7c7976812d2926f8, []int{7} } func (m *MACState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1399,7 +1408,7 @@ type MACState_JoinAccept struct { func (m *MACState_JoinAccept) Reset() { *m = MACState_JoinAccept{} } func (*MACState_JoinAccept) ProtoMessage() {} func (*MACState_JoinAccept) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{7, 0} + return fileDescriptor_end_device_7c7976812d2926f8, []int{7, 0} } func (m *MACState_JoinAccept) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1587,7 +1596,7 @@ type EndDevice struct { func (m *EndDevice) Reset() { *m = EndDevice{} } func (*EndDevice) ProtoMessage() {} func (*EndDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{8} + return fileDescriptor_end_device_7c7976812d2926f8, []int{8} } func (m *EndDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1912,7 +1921,7 @@ type EndDevices struct { func (m *EndDevices) Reset() { *m = EndDevices{} } func (*EndDevices) ProtoMessage() {} func (*EndDevices) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{9} + return fileDescriptor_end_device_7c7976812d2926f8, []int{9} } func (m *EndDevices) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1957,7 +1966,7 @@ type CreateEndDeviceRequest struct { func (m *CreateEndDeviceRequest) Reset() { *m = CreateEndDeviceRequest{} } func (*CreateEndDeviceRequest) ProtoMessage() {} func (*CreateEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{10} + return fileDescriptor_end_device_7c7976812d2926f8, []int{10} } func (m *CreateEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1996,7 +2005,7 @@ type UpdateEndDeviceRequest struct { func (m *UpdateEndDeviceRequest) Reset() { *m = UpdateEndDeviceRequest{} } func (*UpdateEndDeviceRequest) ProtoMessage() {} func (*UpdateEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{11} + return fileDescriptor_end_device_7c7976812d2926f8, []int{11} } func (m *UpdateEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2042,7 +2051,7 @@ type GetEndDeviceRequest struct { func (m *GetEndDeviceRequest) Reset() { *m = GetEndDeviceRequest{} } func (*GetEndDeviceRequest) ProtoMessage() {} func (*GetEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{12} + return fileDescriptor_end_device_7c7976812d2926f8, []int{12} } func (m *GetEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2095,7 +2104,7 @@ type ListEndDevicesRequest struct { func (m *ListEndDevicesRequest) Reset() { *m = ListEndDevicesRequest{} } func (*ListEndDevicesRequest) ProtoMessage() {} func (*ListEndDevicesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{13} + return fileDescriptor_end_device_7c7976812d2926f8, []int{13} } func (m *ListEndDevicesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2162,7 +2171,7 @@ type SetEndDeviceRequest struct { func (m *SetEndDeviceRequest) Reset() { *m = SetEndDeviceRequest{} } func (*SetEndDeviceRequest) ProtoMessage() {} func (*SetEndDeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_end_device_7df2e0db88789f5d, []int{14} + return fileDescriptor_end_device_7c7976812d2926f8, []int{14} } func (m *SetEndDeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -11738,13 +11747,13 @@ var ( ) func init() { - proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_7df2e0db88789f5d) + proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_7c7976812d2926f8) } func init() { - golang_proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_7df2e0db88789f5d) + golang_proto.RegisterFile("lorawan-stack/api/end_device.proto", fileDescriptor_end_device_7c7976812d2926f8) } -var fileDescriptor_end_device_7df2e0db88789f5d = []byte{ +var fileDescriptor_end_device_7c7976812d2926f8 = []byte{ // 3729 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0x4b, 0x70, 0x1b, 0xc7, 0x99, 0x06, 0x40, 0x8a, 0x04, 0x1a, 0x24, 0x1e, 0xcd, 0x87, 0xc6, 0x94, 0x0c, 0xd0, 0x94, 0xec, From 4653cf05bc719a5c5506d71bbaf6273645a042fc Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 19 Feb 2019 13:51:51 +0100 Subject: [PATCH 26/40] ns: Fix MACSettings priority on reset --- pkg/networkserver/utils.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/pkg/networkserver/utils.go b/pkg/networkserver/utils.go index fc43053ac6..3b4e15ce75 100644 --- a/pkg/networkserver/utils.go +++ b/pkg/networkserver/utils.go @@ -137,10 +137,10 @@ func resetMACState(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults ttn dev.MACState.DesiredParameters.Rx2DataRateIndex = dev.MACState.CurrentParameters.Rx2DataRateIndex if dev.GetMACSettings().GetDesiredRx2DataRateIndex() != nil { dev.MACState.DesiredParameters.Rx2DataRateIndex = dev.MACSettings.DesiredRx2DataRateIndex.Value - } else if defaults.DesiredRx2DataRateIndex != nil { - dev.MACState.DesiredParameters.Rx2DataRateIndex = defaults.DesiredRx2DataRateIndex.Value } else if fp.DefaultRx2DataRate != nil { dev.MACState.DesiredParameters.Rx2DataRateIndex = ttnpb.DataRateIndex(*fp.DefaultRx2DataRate) + } else if defaults.DesiredRx2DataRateIndex != nil { + dev.MACState.DesiredParameters.Rx2DataRateIndex = defaults.DesiredRx2DataRateIndex.Value } dev.MACState.CurrentParameters.Rx2Frequency = band.DefaultRx2Parameters.Frequency @@ -152,10 +152,10 @@ func resetMACState(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults ttn dev.MACState.DesiredParameters.Rx2Frequency = dev.MACState.CurrentParameters.Rx2Frequency if dev.MACSettings != nil && dev.GetMACSettings().GetDesiredRx2Frequency() != 0 { dev.MACState.DesiredParameters.Rx2Frequency = dev.MACSettings.DesiredRx2Frequency - } else if defaults.DesiredRx2Frequency != 0 { - dev.MACState.DesiredParameters.Rx2Frequency = defaults.DesiredRx2Frequency } else if fp.Rx2Channel != nil { dev.MACState.DesiredParameters.Rx2Frequency = fp.Rx2Channel.Frequency + } else if defaults.DesiredRx2Frequency != 0 { + dev.MACState.DesiredParameters.Rx2Frequency = defaults.DesiredRx2Frequency } dev.MACState.CurrentParameters.MaxDutyCycle = ttnpb.DUTY_CYCLE_1 @@ -214,6 +214,17 @@ func resetMACState(dev *ttnpb.EndDevice, fps *frequencyplans.Store, defaults ttn EnableUplink: true, }) } + } else if len(defaults.GetFactoryPresetFrequencies()) > 0 { + dev.MACState.CurrentParameters.Channels = make([]*ttnpb.MACParameters_Channel, 0, len(dev.MACSettings.FactoryPresetFrequencies)) + for _, freq := range dev.MACSettings.FactoryPresetFrequencies { + dev.MACState.CurrentParameters.Channels = append(dev.MACState.CurrentParameters.Channels, &ttnpb.MACParameters_Channel{ + MinDataRateIndex: 0, + MaxDataRateIndex: ttnpb.DATA_RATE_15, + UplinkFrequency: freq, + DownlinkFrequency: freq, + EnableUplink: true, + }) + } } else { dev.MACState.CurrentParameters.Channels = make([]*ttnpb.MACParameters_Channel, 0, len(band.UplinkChannels)) for _, upCh := range band.UplinkChannels { From f0c0cf20718753e01579a7d4a3c44610b17518f2 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 19 Feb 2019 14:21:39 +0100 Subject: [PATCH 27/40] api,util: Make RxDelay implement encoding.Text{Unm,M}arshaler --- api/lorawan.proto | 1 + pkg/ttnpb/lorawan.go | 26 ++ pkg/ttnpb/lorawan.pb.go | 807 ++++++++++++++++++++-------------------- 3 files changed, 427 insertions(+), 407 deletions(-) diff --git a/api/lorawan.proto b/api/lorawan.proto index 21115e85ed..7cdff5498a 100644 --- a/api/lorawan.proto +++ b/api/lorawan.proto @@ -680,6 +680,7 @@ enum ADRAckDelayExponent { enum RxDelay { option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.enum_stringer) = false; RX_DELAY_0 = 0; // 1 second. RX_DELAY_1 = 1; // 1 second. diff --git a/pkg/ttnpb/lorawan.go b/pkg/ttnpb/lorawan.go index 3810f815ec..06fef6fbc7 100644 --- a/pkg/ttnpb/lorawan.go +++ b/pkg/ttnpb/lorawan.go @@ -186,3 +186,29 @@ func (v *DataRateIndex) UnmarshalText(b []byte) error { *v = DataRateIndex(i) return nil } + +// String implements fmt.Stringer. +func (v RxDelay) String() string { + return strconv.Itoa(int(v)) +} + +// MarshalText implements encoding.TextMarshaler interface. +func (v RxDelay) MarshalText() ([]byte, error) { + return []byte(v.String()), nil +} + +// UnmarshalText implements encoding.TextUnmarshaler interface. +func (v *RxDelay) UnmarshalText(b []byte) error { + i, err := strconv.Atoi(string(b)) + if err != nil { + return errCouldNotParse("RxDelay")(string(b)).WithCause(err) + } + if i > int(RX_DELAY_15) { + return errFieldHasMax.WithAttributes( + "lorawan_field", "RxDelay", + "max", RX_DELAY_15, + ) + } + *v = RxDelay(i) + return nil +} diff --git a/pkg/ttnpb/lorawan.pb.go b/pkg/ttnpb/lorawan.pb.go index 3248fd5f36..acd295d43d 100644 --- a/pkg/ttnpb/lorawan.pb.go +++ b/pkg/ttnpb/lorawan.pb.go @@ -73,7 +73,7 @@ var MType_value = map[string]int32{ } func (MType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{0} + return fileDescriptor_lorawan_58aef822c5219cad, []int{0} } type Major int32 @@ -90,7 +90,7 @@ var Major_value = map[string]int32{ } func (Major) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{1} + return fileDescriptor_lorawan_58aef822c5219cad, []int{1} } type MACVersion int32 @@ -119,7 +119,7 @@ var MACVersion_value = map[string]int32{ } func (MACVersion) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{2} + return fileDescriptor_lorawan_58aef822c5219cad, []int{2} } type PHYVersion int32 @@ -154,7 +154,7 @@ var PHYVersion_value = map[string]int32{ } func (PHYVersion) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{3} + return fileDescriptor_lorawan_58aef822c5219cad, []int{3} } type DataRateIndex int32 @@ -216,7 +216,7 @@ var DataRateIndex_value = map[string]int32{ } func (DataRateIndex) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{4} + return fileDescriptor_lorawan_58aef822c5219cad, []int{4} } type RejoinType int32 @@ -239,7 +239,7 @@ var RejoinType_value = map[string]int32{ } func (RejoinType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{5} + return fileDescriptor_lorawan_58aef822c5219cad, []int{5} } type CFListType int32 @@ -259,7 +259,7 @@ var CFListType_value = map[string]int32{ } func (CFListType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{6} + return fileDescriptor_lorawan_58aef822c5219cad, []int{6} } type Class int32 @@ -282,7 +282,7 @@ var Class_value = map[string]int32{ } func (Class) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{7} + return fileDescriptor_lorawan_58aef822c5219cad, []int{7} } type TxSchedulePriority int32 @@ -317,7 +317,7 @@ var TxSchedulePriority_value = map[string]int32{ } func (TxSchedulePriority) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{8} + return fileDescriptor_lorawan_58aef822c5219cad, []int{8} } type MACCommandIdentifier int32 @@ -394,7 +394,7 @@ var MACCommandIdentifier_value = map[string]int32{ } func (MACCommandIdentifier) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{9} + return fileDescriptor_lorawan_58aef822c5219cad, []int{9} } type AggregatedDutyCycle int32 @@ -456,7 +456,7 @@ var AggregatedDutyCycle_value = map[string]int32{ } func (AggregatedDutyCycle) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{10} + return fileDescriptor_lorawan_58aef822c5219cad, []int{10} } type PingSlotPeriod int32 @@ -494,7 +494,7 @@ var PingSlotPeriod_value = map[string]int32{ } func (PingSlotPeriod) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{11} + return fileDescriptor_lorawan_58aef822c5219cad, []int{11} } type RejoinCountExponent int32 @@ -556,7 +556,7 @@ var RejoinCountExponent_value = map[string]int32{ } func (RejoinCountExponent) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{12} + return fileDescriptor_lorawan_58aef822c5219cad, []int{12} } type RejoinTimeExponent int32 @@ -618,7 +618,7 @@ var RejoinTimeExponent_value = map[string]int32{ } func (RejoinTimeExponent) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{13} + return fileDescriptor_lorawan_58aef822c5219cad, []int{13} } type RejoinPeriodExponent int32 @@ -656,7 +656,7 @@ var RejoinPeriodExponent_value = map[string]int32{ } func (RejoinPeriodExponent) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{14} + return fileDescriptor_lorawan_58aef822c5219cad, []int{14} } type DeviceEIRP int32 @@ -718,7 +718,7 @@ var DeviceEIRP_value = map[string]int32{ } func (DeviceEIRP) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{15} + return fileDescriptor_lorawan_58aef822c5219cad, []int{15} } type ADRAckLimitExponent int32 @@ -780,7 +780,7 @@ var ADRAckLimitExponent_value = map[string]int32{ } func (ADRAckLimitExponent) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{16} + return fileDescriptor_lorawan_58aef822c5219cad, []int{16} } type ADRAckDelayExponent int32 @@ -842,7 +842,7 @@ var ADRAckDelayExponent_value = map[string]int32{ } func (ADRAckDelayExponent) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{17} + return fileDescriptor_lorawan_58aef822c5219cad, []int{17} } type RxDelay int32 @@ -904,7 +904,7 @@ var RxDelay_value = map[string]int32{ } func (RxDelay) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18} } type Minor int32 @@ -966,7 +966,7 @@ var Minor_value = map[string]int32{ } func (Minor) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{19} + return fileDescriptor_lorawan_58aef822c5219cad, []int{19} } type Message struct { @@ -991,7 +991,7 @@ type Message struct { func (m *Message) Reset() { *m = Message{} } func (*Message) ProtoMessage() {} func (*Message) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{0} + return fileDescriptor_lorawan_58aef822c5219cad, []int{0} } func (m *Message) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1209,7 +1209,7 @@ type MHDR struct { func (m *MHDR) Reset() { *m = MHDR{} } func (*MHDR) ProtoMessage() {} func (*MHDR) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{1} + return fileDescriptor_lorawan_58aef822c5219cad, []int{1} } func (m *MHDR) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1264,7 +1264,7 @@ type MACPayload struct { func (m *MACPayload) Reset() { *m = MACPayload{} } func (*MACPayload) ProtoMessage() {} func (*MACPayload) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{2} + return fileDescriptor_lorawan_58aef822c5219cad, []int{2} } func (m *MACPayload) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1326,7 +1326,7 @@ type FHDR struct { func (m *FHDR) Reset() { *m = FHDR{} } func (*FHDR) ProtoMessage() {} func (*FHDR) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{3} + return fileDescriptor_lorawan_58aef822c5219cad, []int{3} } func (m *FHDR) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1382,7 +1382,7 @@ type FCtrl struct { func (m *FCtrl) Reset() { *m = FCtrl{} } func (*FCtrl) ProtoMessage() {} func (*FCtrl) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{4} + return fileDescriptor_lorawan_58aef822c5219cad, []int{4} } func (m *FCtrl) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1457,7 +1457,7 @@ type JoinRequestPayload struct { func (m *JoinRequestPayload) Reset() { *m = JoinRequestPayload{} } func (*JoinRequestPayload) ProtoMessage() {} func (*JoinRequestPayload) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{5} + return fileDescriptor_lorawan_58aef822c5219cad, []int{5} } func (m *JoinRequestPayload) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1499,7 +1499,7 @@ type RejoinRequestPayload struct { func (m *RejoinRequestPayload) Reset() { *m = RejoinRequestPayload{} } func (*RejoinRequestPayload) ProtoMessage() {} func (*RejoinRequestPayload) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{6} + return fileDescriptor_lorawan_58aef822c5219cad, []int{6} } func (m *RejoinRequestPayload) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1557,7 +1557,7 @@ type JoinAcceptPayload struct { func (m *JoinAcceptPayload) Reset() { *m = JoinAcceptPayload{} } func (*JoinAcceptPayload) ProtoMessage() {} func (*JoinAcceptPayload) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{7} + return fileDescriptor_lorawan_58aef822c5219cad, []int{7} } func (m *JoinAcceptPayload) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1619,7 +1619,7 @@ type DLSettings struct { func (m *DLSettings) Reset() { *m = DLSettings{} } func (*DLSettings) ProtoMessage() {} func (*DLSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{8} + return fileDescriptor_lorawan_58aef822c5219cad, []int{8} } func (m *DLSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1686,7 +1686,7 @@ type CFList struct { func (m *CFList) Reset() { *m = CFList{} } func (*CFList) ProtoMessage() {} func (*CFList) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{9} + return fileDescriptor_lorawan_58aef822c5219cad, []int{9} } func (m *CFList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1747,7 +1747,7 @@ type LoRaDataRate struct { func (m *LoRaDataRate) Reset() { *m = LoRaDataRate{} } func (*LoRaDataRate) ProtoMessage() {} func (*LoRaDataRate) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{10} + return fileDescriptor_lorawan_58aef822c5219cad, []int{10} } func (m *LoRaDataRate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1800,7 +1800,7 @@ type FSKDataRate struct { func (m *FSKDataRate) Reset() { *m = FSKDataRate{} } func (*FSKDataRate) ProtoMessage() {} func (*FSKDataRate) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{11} + return fileDescriptor_lorawan_58aef822c5219cad, []int{11} } func (m *FSKDataRate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1848,7 +1848,7 @@ type DataRate struct { func (m *DataRate) Reset() { *m = DataRate{} } func (*DataRate) ProtoMessage() {} func (*DataRate) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{12} + return fileDescriptor_lorawan_58aef822c5219cad, []int{12} } func (m *DataRate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2026,7 +2026,7 @@ type TxSettings struct { func (m *TxSettings) Reset() { *m = TxSettings{} } func (*TxSettings) ProtoMessage() {} func (*TxSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{13} + return fileDescriptor_lorawan_58aef822c5219cad, []int{13} } func (m *TxSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2142,7 +2142,7 @@ type GatewayAntennaIdentifiers struct { func (m *GatewayAntennaIdentifiers) Reset() { *m = GatewayAntennaIdentifiers{} } func (*GatewayAntennaIdentifiers) ProtoMessage() {} func (*GatewayAntennaIdentifiers) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{14} + return fileDescriptor_lorawan_58aef822c5219cad, []int{14} } func (m *GatewayAntennaIdentifiers) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2188,7 +2188,7 @@ type UplinkToken struct { func (m *UplinkToken) Reset() { *m = UplinkToken{} } func (*UplinkToken) ProtoMessage() {} func (*UplinkToken) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{15} + return fileDescriptor_lorawan_58aef822c5219cad, []int{15} } func (m *UplinkToken) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2239,7 +2239,7 @@ type DownlinkPath struct { func (m *DownlinkPath) Reset() { *m = DownlinkPath{} } func (*DownlinkPath) ProtoMessage() {} func (*DownlinkPath) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{16} + return fileDescriptor_lorawan_58aef822c5219cad, []int{16} } func (m *DownlinkPath) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2416,7 +2416,7 @@ type TxRequest struct { func (m *TxRequest) Reset() { *m = TxRequest{} } func (*TxRequest) ProtoMessage() {} func (*TxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{17} + return fileDescriptor_lorawan_58aef822c5219cad, []int{17} } func (m *TxRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2557,7 +2557,7 @@ type MACCommand struct { func (m *MACCommand) Reset() { *m = MACCommand{} } func (*MACCommand) ProtoMessage() {} func (*MACCommand) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18} } func (m *MACCommand) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3580,7 +3580,7 @@ type MACCommand_ResetInd struct { func (m *MACCommand_ResetInd) Reset() { *m = MACCommand_ResetInd{} } func (*MACCommand_ResetInd) ProtoMessage() {} func (*MACCommand_ResetInd) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 0} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 0} } func (m *MACCommand_ResetInd) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3625,7 +3625,7 @@ type MACCommand_ResetConf struct { func (m *MACCommand_ResetConf) Reset() { *m = MACCommand_ResetConf{} } func (*MACCommand_ResetConf) ProtoMessage() {} func (*MACCommand_ResetConf) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 1} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 1} } func (m *MACCommand_ResetConf) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3672,7 +3672,7 @@ type MACCommand_LinkCheckAns struct { func (m *MACCommand_LinkCheckAns) Reset() { *m = MACCommand_LinkCheckAns{} } func (*MACCommand_LinkCheckAns) ProtoMessage() {} func (*MACCommand_LinkCheckAns) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 2} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 2} } func (m *MACCommand_LinkCheckAns) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3728,7 +3728,7 @@ type MACCommand_LinkADRReq struct { func (m *MACCommand_LinkADRReq) Reset() { *m = MACCommand_LinkADRReq{} } func (*MACCommand_LinkADRReq) ProtoMessage() {} func (*MACCommand_LinkADRReq) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 3} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 3} } func (m *MACCommand_LinkADRReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3803,7 +3803,7 @@ type MACCommand_LinkADRAns struct { func (m *MACCommand_LinkADRAns) Reset() { *m = MACCommand_LinkADRAns{} } func (*MACCommand_LinkADRAns) ProtoMessage() {} func (*MACCommand_LinkADRAns) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 4} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 4} } func (m *MACCommand_LinkADRAns) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3862,7 +3862,7 @@ type MACCommand_DutyCycleReq struct { func (m *MACCommand_DutyCycleReq) Reset() { *m = MACCommand_DutyCycleReq{} } func (*MACCommand_DutyCycleReq) ProtoMessage() {} func (*MACCommand_DutyCycleReq) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 5} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 5} } func (m *MACCommand_DutyCycleReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3909,7 +3909,7 @@ type MACCommand_RxParamSetupReq struct { func (m *MACCommand_RxParamSetupReq) Reset() { *m = MACCommand_RxParamSetupReq{} } func (*MACCommand_RxParamSetupReq) ProtoMessage() {} func (*MACCommand_RxParamSetupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 6} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 6} } func (m *MACCommand_RxParamSetupReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3970,7 +3970,7 @@ type MACCommand_RxParamSetupAns struct { func (m *MACCommand_RxParamSetupAns) Reset() { *m = MACCommand_RxParamSetupAns{} } func (*MACCommand_RxParamSetupAns) ProtoMessage() {} func (*MACCommand_RxParamSetupAns) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 7} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 7} } func (m *MACCommand_RxParamSetupAns) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4035,7 +4035,7 @@ type MACCommand_DevStatusAns struct { func (m *MACCommand_DevStatusAns) Reset() { *m = MACCommand_DevStatusAns{} } func (*MACCommand_DevStatusAns) ProtoMessage() {} func (*MACCommand_DevStatusAns) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 8} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 8} } func (m *MACCommand_DevStatusAns) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4090,7 +4090,7 @@ type MACCommand_NewChannelReq struct { func (m *MACCommand_NewChannelReq) Reset() { *m = MACCommand_NewChannelReq{} } func (*MACCommand_NewChannelReq) ProtoMessage() {} func (*MACCommand_NewChannelReq) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 9} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 9} } func (m *MACCommand_NewChannelReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4157,7 +4157,7 @@ type MACCommand_NewChannelAns struct { func (m *MACCommand_NewChannelAns) Reset() { *m = MACCommand_NewChannelAns{} } func (*MACCommand_NewChannelAns) ProtoMessage() {} func (*MACCommand_NewChannelAns) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 10} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 10} } func (m *MACCommand_NewChannelAns) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4210,7 +4210,7 @@ type MACCommand_DLChannelReq struct { func (m *MACCommand_DLChannelReq) Reset() { *m = MACCommand_DLChannelReq{} } func (*MACCommand_DLChannelReq) ProtoMessage() {} func (*MACCommand_DLChannelReq) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 11} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 11} } func (m *MACCommand_DLChannelReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4263,7 +4263,7 @@ type MACCommand_DLChannelAns struct { func (m *MACCommand_DLChannelAns) Reset() { *m = MACCommand_DLChannelAns{} } func (*MACCommand_DLChannelAns) ProtoMessage() {} func (*MACCommand_DLChannelAns) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 12} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 12} } func (m *MACCommand_DLChannelAns) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4315,7 +4315,7 @@ type MACCommand_RxTimingSetupReq struct { func (m *MACCommand_RxTimingSetupReq) Reset() { *m = MACCommand_RxTimingSetupReq{} } func (*MACCommand_RxTimingSetupReq) ProtoMessage() {} func (*MACCommand_RxTimingSetupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 13} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 13} } func (m *MACCommand_RxTimingSetupReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4364,7 +4364,7 @@ type MACCommand_TxParamSetupReq struct { func (m *MACCommand_TxParamSetupReq) Reset() { *m = MACCommand_TxParamSetupReq{} } func (*MACCommand_TxParamSetupReq) ProtoMessage() {} func (*MACCommand_TxParamSetupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 14} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 14} } func (m *MACCommand_TxParamSetupReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4423,7 +4423,7 @@ type MACCommand_RekeyInd struct { func (m *MACCommand_RekeyInd) Reset() { *m = MACCommand_RekeyInd{} } func (*MACCommand_RekeyInd) ProtoMessage() {} func (*MACCommand_RekeyInd) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 15} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 15} } func (m *MACCommand_RekeyInd) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4468,7 +4468,7 @@ type MACCommand_RekeyConf struct { func (m *MACCommand_RekeyConf) Reset() { *m = MACCommand_RekeyConf{} } func (*MACCommand_RekeyConf) ProtoMessage() {} func (*MACCommand_RekeyConf) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 16} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 16} } func (m *MACCommand_RekeyConf) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4516,7 +4516,7 @@ type MACCommand_ADRParamSetupReq struct { func (m *MACCommand_ADRParamSetupReq) Reset() { *m = MACCommand_ADRParamSetupReq{} } func (*MACCommand_ADRParamSetupReq) ProtoMessage() {} func (*MACCommand_ADRParamSetupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 17} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 17} } func (m *MACCommand_ADRParamSetupReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4568,7 +4568,7 @@ type MACCommand_DeviceTimeAns struct { func (m *MACCommand_DeviceTimeAns) Reset() { *m = MACCommand_DeviceTimeAns{} } func (*MACCommand_DeviceTimeAns) ProtoMessage() {} func (*MACCommand_DeviceTimeAns) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 18} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 18} } func (m *MACCommand_DeviceTimeAns) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4617,7 +4617,7 @@ type MACCommand_ForceRejoinReq struct { func (m *MACCommand_ForceRejoinReq) Reset() { *m = MACCommand_ForceRejoinReq{} } func (*MACCommand_ForceRejoinReq) ProtoMessage() {} func (*MACCommand_ForceRejoinReq) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 19} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 19} } func (m *MACCommand_ForceRejoinReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4686,7 +4686,7 @@ type MACCommand_RejoinParamSetupReq struct { func (m *MACCommand_RejoinParamSetupReq) Reset() { *m = MACCommand_RejoinParamSetupReq{} } func (*MACCommand_RejoinParamSetupReq) ProtoMessage() {} func (*MACCommand_RejoinParamSetupReq) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 20} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 20} } func (m *MACCommand_RejoinParamSetupReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4738,7 +4738,7 @@ type MACCommand_RejoinParamSetupAns struct { func (m *MACCommand_RejoinParamSetupAns) Reset() { *m = MACCommand_RejoinParamSetupAns{} } func (*MACCommand_RejoinParamSetupAns) ProtoMessage() {} func (*MACCommand_RejoinParamSetupAns) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 21} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 21} } func (m *MACCommand_RejoinParamSetupAns) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4783,7 +4783,7 @@ type MACCommand_PingSlotInfoReq struct { func (m *MACCommand_PingSlotInfoReq) Reset() { *m = MACCommand_PingSlotInfoReq{} } func (*MACCommand_PingSlotInfoReq) ProtoMessage() {} func (*MACCommand_PingSlotInfoReq) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 22} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 22} } func (m *MACCommand_PingSlotInfoReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4829,7 +4829,7 @@ type MACCommand_PingSlotChannelReq struct { func (m *MACCommand_PingSlotChannelReq) Reset() { *m = MACCommand_PingSlotChannelReq{} } func (*MACCommand_PingSlotChannelReq) ProtoMessage() {} func (*MACCommand_PingSlotChannelReq) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 23} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 23} } func (m *MACCommand_PingSlotChannelReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4882,7 +4882,7 @@ type MACCommand_PingSlotChannelAns struct { func (m *MACCommand_PingSlotChannelAns) Reset() { *m = MACCommand_PingSlotChannelAns{} } func (*MACCommand_PingSlotChannelAns) ProtoMessage() {} func (*MACCommand_PingSlotChannelAns) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 24} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 24} } func (m *MACCommand_PingSlotChannelAns) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4935,7 +4935,7 @@ type MACCommand_BeaconTimingAns struct { func (m *MACCommand_BeaconTimingAns) Reset() { *m = MACCommand_BeaconTimingAns{} } func (*MACCommand_BeaconTimingAns) ProtoMessage() {} func (*MACCommand_BeaconTimingAns) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 25} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 25} } func (m *MACCommand_BeaconTimingAns) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4987,7 +4987,7 @@ type MACCommand_BeaconFreqReq struct { func (m *MACCommand_BeaconFreqReq) Reset() { *m = MACCommand_BeaconFreqReq{} } func (*MACCommand_BeaconFreqReq) ProtoMessage() {} func (*MACCommand_BeaconFreqReq) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 26} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 26} } func (m *MACCommand_BeaconFreqReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5032,7 +5032,7 @@ type MACCommand_BeaconFreqAns struct { func (m *MACCommand_BeaconFreqAns) Reset() { *m = MACCommand_BeaconFreqAns{} } func (*MACCommand_BeaconFreqAns) ProtoMessage() {} func (*MACCommand_BeaconFreqAns) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 27} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 27} } func (m *MACCommand_BeaconFreqAns) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5077,7 +5077,7 @@ type MACCommand_DeviceModeInd struct { func (m *MACCommand_DeviceModeInd) Reset() { *m = MACCommand_DeviceModeInd{} } func (*MACCommand_DeviceModeInd) ProtoMessage() {} func (*MACCommand_DeviceModeInd) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 28} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 28} } func (m *MACCommand_DeviceModeInd) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5122,7 +5122,7 @@ type MACCommand_DeviceModeConf struct { func (m *MACCommand_DeviceModeConf) Reset() { *m = MACCommand_DeviceModeConf{} } func (*MACCommand_DeviceModeConf) ProtoMessage() {} func (*MACCommand_DeviceModeConf) Descriptor() ([]byte, []int) { - return fileDescriptor_lorawan_76222860124625e1, []int{18, 29} + return fileDescriptor_lorawan_58aef822c5219cad, []int{18, 29} } func (m *MACCommand_DeviceModeConf) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5403,13 +5403,6 @@ func (x ADRAckDelayExponent) String() string { } return strconv.Itoa(int(x)) } -func (x RxDelay) String() string { - s, ok := RxDelay_name[int32(x)] - if ok { - return s - } - return strconv.Itoa(int(x)) -} func (x Minor) String() string { s, ok := Minor_name[int32(x)] if ok { @@ -19831,337 +19824,337 @@ var ( ) func init() { - proto.RegisterFile("lorawan-stack/api/lorawan.proto", fileDescriptor_lorawan_76222860124625e1) + proto.RegisterFile("lorawan-stack/api/lorawan.proto", fileDescriptor_lorawan_58aef822c5219cad) } func init() { - golang_proto.RegisterFile("lorawan-stack/api/lorawan.proto", fileDescriptor_lorawan_76222860124625e1) -} - -var fileDescriptor_lorawan_76222860124625e1 = []byte{ - // 5196 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x7b, 0x4d, 0x6c, 0x23, 0xc9, - 0x75, 0x3f, 0x5b, 0x24, 0x45, 0xea, 0x91, 0x14, 0x7b, 0x4a, 0x9a, 0x19, 0x0d, 0xbd, 0x4b, 0xad, - 0x35, 0xfb, 0xc7, 0x7f, 0x3c, 0xf6, 0x68, 0x24, 0x4a, 0xa3, 0xd5, 0x7a, 0xfd, 0xc5, 0x2f, 0xad, - 0xb8, 0x23, 0x91, 0x72, 0x53, 0x9a, 0xd9, 0x31, 0x6c, 0x74, 0x5a, 0xec, 0xa6, 0xc4, 0x11, 0xd9, - 0xcd, 0x6d, 0xb6, 0x46, 0x52, 0x0e, 0xc1, 0x02, 0xb9, 0x2c, 0x90, 0x43, 0x8c, 0x00, 0x06, 0x62, - 0xe4, 0x60, 0x23, 0xc9, 0xc1, 0x40, 0x10, 0xc4, 0x40, 0x10, 0x64, 0x8f, 0x0e, 0x90, 0x83, 0x91, - 0xd3, 0x06, 0xb9, 0x18, 0x0e, 0x22, 0x7b, 0x38, 0x17, 0xe7, 0x92, 0xf8, 0xb8, 0xc7, 0xe0, 0x55, - 0x55, 0xb3, 0xab, 0xbb, 0x39, 0x92, 0x66, 0x77, 0x7d, 0x52, 0xd7, 0xaf, 0x5f, 0xbd, 0x7a, 0xf5, - 0x3e, 0xeb, 0x55, 0x53, 0x30, 0xdf, 0xb5, 0x6c, 0xed, 0x44, 0x33, 0xef, 0x0d, 0x1c, 0xad, 0x75, - 0x74, 0x5f, 0xeb, 0x77, 0xee, 0x73, 0x64, 0xb1, 0x6f, 0x5b, 0x8e, 0x45, 0xa6, 0x1d, 0xc7, 0x5c, - 0x74, 0xa1, 0x67, 0x2b, 0xb9, 0x7b, 0x07, 0x1d, 0xe7, 0xf0, 0x78, 0x7f, 0xb1, 0x65, 0xf5, 0xee, - 0x1f, 0x58, 0x07, 0xd6, 0x7d, 0x4a, 0xb6, 0x7f, 0xdc, 0xa6, 0x23, 0x3a, 0xa0, 0x4f, 0x6c, 0x7a, - 0x6e, 0x4d, 0x20, 0xef, 0x9d, 0x74, 0x9c, 0x23, 0xeb, 0xe4, 0xfe, 0x81, 0x75, 0x8f, 0xbe, 0xbc, - 0xf7, 0x4c, 0xeb, 0x76, 0x74, 0xcd, 0xb1, 0xec, 0xc1, 0xfd, 0xd1, 0x23, 0x9f, 0xf7, 0xda, 0x81, - 0x65, 0x1d, 0x74, 0x0d, 0x8f, 0xfb, 0xc0, 0xb1, 0x8f, 0x5b, 0x0e, 0x7f, 0x3b, 0x1f, 0x7c, 0xeb, - 0x74, 0x7a, 0xc6, 0xc0, 0xd1, 0x7a, 0x7d, 0x4e, 0x70, 0x3b, 0xbc, 0xad, 0x8e, 0x6e, 0x98, 0x4e, - 0xa7, 0xdd, 0x31, 0xec, 0x01, 0x23, 0x5a, 0xf8, 0xb7, 0x28, 0x24, 0xb6, 0x8d, 0xc1, 0x40, 0x3b, - 0x30, 0xc8, 0x0a, 0xc4, 0x7b, 0xea, 0xa1, 0x6e, 0xcf, 0x49, 0x6f, 0x48, 0x77, 0x52, 0x85, 0xd9, - 0x45, 0xff, 0xb6, 0x17, 0xb7, 0x37, 0x2b, 0x4a, 0x29, 0xf9, 0xcb, 0xf3, 0xf9, 0xc8, 0x27, 0xe7, - 0xf3, 0x92, 0x12, 0xeb, 0x6d, 0xea, 0x36, 0xb9, 0x05, 0xd1, 0x5e, 0xa7, 0x35, 0x37, 0xf1, 0x86, - 0x74, 0x27, 0x5d, 0x4a, 0x0c, 0xcf, 0xe7, 0xa3, 0xdb, 0xb5, 0xb2, 0x82, 0x18, 0xd9, 0x86, 0x54, - 0x4f, 0x6b, 0xa9, 0x7d, 0xed, 0xac, 0x6b, 0x69, 0xfa, 0x5c, 0x94, 0x72, 0xcd, 0x85, 0xb8, 0x16, - 0xcb, 0x3b, 0x8c, 0xa2, 0x34, 0x3d, 0x3c, 0x9f, 0x07, 0x6f, 0xbc, 0x19, 0x51, 0xa0, 0xa7, 0xb5, - 0xf8, 0x88, 0x3c, 0x82, 0xd9, 0xa7, 0x56, 0xc7, 0x54, 0x6d, 0xe3, 0x83, 0x63, 0x63, 0xe0, 0x8c, - 0xf8, 0xc6, 0x28, 0xdf, 0x85, 0x20, 0xdf, 0xf7, 0xac, 0x8e, 0xa9, 0x30, 0x52, 0x8f, 0x1f, 0x79, - 0x1a, 0x42, 0x49, 0x13, 0x66, 0x28, 0x5f, 0xad, 0xd5, 0x32, 0xfa, 0x1e, 0xdb, 0x38, 0x65, 0xfb, - 0xe5, 0x71, 0x6c, 0x8b, 0x94, 0xd2, 0xe3, 0x7a, 0xed, 0x69, 0x10, 0x24, 0xdf, 0x87, 0x1b, 0xb6, - 0x31, 0x56, 0xdc, 0x49, 0xca, 0xf7, 0xcd, 0x20, 0x5f, 0xc5, 0x78, 0x3a, 0x4e, 0xe0, 0x59, 0x7b, - 0x0c, 0xfe, 0xf5, 0xd8, 0xc7, 0x3f, 0x9d, 0x8f, 0x94, 0xa6, 0x20, 0xc1, 0x81, 0xf7, 0x62, 0xc9, - 0x84, 0x9c, 0x5c, 0xd0, 0x20, 0x86, 0x36, 0x22, 0x5f, 0x83, 0xc9, 0x9e, 0xea, 0x9c, 0xf5, 0x0d, - 0x6a, 0xc9, 0xe9, 0xc2, 0xf5, 0x90, 0xce, 0x77, 0xcf, 0xfa, 0x86, 0x12, 0xef, 0xe1, 0x1f, 0xf2, - 0x55, 0x88, 0xf7, 0xb4, 0xa7, 0x96, 0x4d, 0x6d, 0x38, 0x8e, 0x18, 0x5f, 0x2a, 0x8c, 0x66, 0xe1, - 0xd7, 0x12, 0x08, 0x16, 0x42, 0x97, 0x69, 0x5f, 0xe4, 0x32, 0x1b, 0x01, 0x97, 0x69, 0xa3, 0xcb, - 0xe4, 0x61, 0xb2, 0xad, 0xf6, 0x2d, 0xdb, 0xa1, 0x2b, 0x66, 0x4a, 0x89, 0xe1, 0x6f, 0xe6, 0xa3, - 0x73, 0x1f, 0x4e, 0x28, 0xf1, 0xf6, 0x8e, 0x65, 0x3b, 0xe4, 0x3e, 0xa4, 0xda, 0x76, 0xcf, 0xe7, - 0x37, 0x69, 0xe6, 0x1b, 0x1b, 0xca, 0x36, 0x5f, 0x59, 0x81, 0xb6, 0xdd, 0x73, 0xa5, 0xf8, 0x0e, - 0x64, 0x75, 0xa3, 0x65, 0xe9, 0x86, 0x1e, 0x70, 0x8a, 0x9b, 0x8b, 0x2c, 0x48, 0x16, 0xdd, 0x20, - 0x59, 0x6c, 0xd2, 0x10, 0x52, 0xa6, 0x39, 0xbd, 0x4f, 0xa1, 0x0b, 0xff, 0x21, 0x41, 0x0c, 0x25, - 0x26, 0x8f, 0x21, 0xa9, 0x1b, 0xcf, 0x54, 0x4d, 0xe7, 0x3b, 0x4b, 0x97, 0xbe, 0x81, 0x7b, 0xf8, - 0xf5, 0xf9, 0xfc, 0xea, 0x81, 0xb5, 0xe8, 0x1c, 0x1a, 0xce, 0x61, 0xc7, 0x3c, 0x18, 0x2c, 0x9a, - 0x86, 0x73, 0x62, 0xd9, 0x47, 0xf7, 0xfd, 0x91, 0xd6, 0x3f, 0x3a, 0xb8, 0x8f, 0xda, 0x1f, 0x2c, - 0x56, 0x8c, 0x67, 0x45, 0x5d, 0xb7, 0x95, 0x84, 0xce, 0x1e, 0xc8, 0x1a, 0x6e, 0xbd, 0xe5, 0xd8, - 0x5d, 0xba, 0xf5, 0x54, 0x58, 0xd9, 0x1b, 0x65, 0xc7, 0xee, 0x0a, 0x1a, 0x8b, 0xb7, 0x11, 0x20, - 0xaf, 0xa3, 0x9e, 0x5b, 0xa6, 0x43, 0x95, 0x91, 0x29, 0x25, 0x87, 0xbf, 0x99, 0x8f, 0xcd, 0x7d, - 0xf8, 0x61, 0x4c, 0x89, 0xb5, 0xcb, 0xa6, 0x43, 0xae, 0x23, 0x5b, 0xab, 0xef, 0x0c, 0xe8, 0xbe, - 0xd3, 0x4a, 0xbc, 0xdd, 0xe8, 0x3b, 0x03, 0xbe, 0xab, 0x1f, 0x4b, 0x10, 0xa7, 0x6c, 0x31, 0x56, - 0x35, 0xbe, 0xa3, 0x24, 0x8b, 0xd5, 0x62, 0x45, 0x51, 0x10, 0x23, 0xf7, 0x20, 0xa5, 0xe9, 0xb6, - 0xaa, 0xb5, 0x8e, 0xd0, 0x61, 0xa9, 0x74, 0xc9, 0x52, 0x66, 0x78, 0x3e, 0x3f, 0x55, 0xac, 0x28, - 0xc5, 0xd6, 0x91, 0x62, 0x7c, 0xa0, 0x4c, 0x69, 0xba, 0xcd, 0x1e, 0x89, 0x0c, 0x51, 0xad, 0x75, - 0x44, 0xa5, 0x49, 0x2a, 0xf8, 0x48, 0xbe, 0x04, 0x53, 0x6d, 0xb5, 0x6f, 0x98, 0x7a, 0xc7, 0x3c, - 0xa0, 0x52, 0x24, 0x95, 0x64, 0x7b, 0x87, 0x8d, 0xc9, 0x4d, 0x48, 0xb4, 0xba, 0xda, 0x60, 0xa0, - 0xee, 0xd3, 0xb0, 0x4a, 0x2a, 0x93, 0x74, 0x58, 0x5a, 0xf8, 0xe7, 0x09, 0x20, 0xe1, 0x40, 0x25, - 0x7f, 0x04, 0x49, 0x1a, 0x3b, 0xc6, 0x71, 0x87, 0xeb, 0xbf, 0xca, 0xf5, 0x5f, 0x78, 0x25, 0xfd, - 0x57, 0xf7, 0x6a, 0x6b, 0xab, 0xc3, 0xf3, 0xf9, 0x04, 0xae, 0x51, 0xdd, 0xab, 0x29, 0x09, 0x64, - 0x5b, 0x3d, 0xee, 0x90, 0x1f, 0x00, 0xda, 0x84, 0x2e, 0xc0, 0x52, 0x57, 0xe5, 0x73, 0x2d, 0x30, - 0x59, 0x31, 0x9e, 0x21, 0xff, 0x49, 0xdd, 0x78, 0x86, 0xec, 0xbf, 0x07, 0x53, 0xc8, 0xde, 0xb4, - 0xcc, 0x96, 0xc1, 0x1d, 0xf8, 0x9b, 0x7c, 0x81, 0x07, 0xaf, 0xea, 0x41, 0x75, 0x64, 0xa2, 0xa0, - 0x43, 0xd2, 0x27, 0x6e, 0xd5, 0x1f, 0x45, 0x61, 0x76, 0x5c, 0xce, 0x20, 0xef, 0x40, 0x8a, 0x67, - 0x1e, 0x21, 0x03, 0xe4, 0xc6, 0xa7, 0x1b, 0x9a, 0x06, 0xc0, 0x1e, 0x3d, 0x93, 0xef, 0xc1, 0xa4, - 0x69, 0x38, 0x6a, 0x47, 0xe7, 0x5a, 0x29, 0x7f, 0x26, 0xad, 0xd4, 0x0d, 0xa7, 0x56, 0x19, 0x9e, - 0xcf, 0xc7, 0xe9, 0x83, 0x12, 0x37, 0x0d, 0xa7, 0xe6, 0x37, 0x6a, 0xf4, 0x0f, 0x6d, 0xd4, 0xd8, - 0x1f, 0xc0, 0xa8, 0xaf, 0x03, 0x57, 0x15, 0x8d, 0x44, 0x74, 0xe4, 0x8c, 0x32, 0xc5, 0x90, 0xb2, - 0xe9, 0x70, 0xbb, 0xfc, 0x69, 0x0c, 0xae, 0x85, 0x6a, 0x04, 0x79, 0x0d, 0xa6, 0x0c, 0xb3, 0x65, - 0x9f, 0xf5, 0x1d, 0x43, 0x67, 0x1e, 0xad, 0x78, 0x00, 0xf9, 0x01, 0x00, 0x65, 0xcb, 0xdc, 0x85, - 0x69, 0xfe, 0x5b, 0x5c, 0xf4, 0xb5, 0x57, 0x12, 0x1d, 0x57, 0x66, 0xfe, 0x32, 0xf5, 0xd4, 0x7d, - 0x14, 0x8c, 0x1a, 0xfd, 0xc2, 0x8d, 0x2a, 0x66, 0xca, 0xd8, 0x17, 0x99, 0x29, 0xab, 0x90, 0xd2, - 0xbb, 0xea, 0xc0, 0x70, 0x1c, 0x9c, 0xcf, 0xab, 0x71, 0xc8, 0x8d, 0x2b, 0x5b, 0x4d, 0x4e, 0x21, - 0xe4, 0x4c, 0xd0, 0xbb, 0x2e, 0x4a, 0x0a, 0x90, 0xb4, 0x4f, 0x55, 0xdd, 0xe8, 0x6a, 0x67, 0xb4, - 0xf2, 0x4e, 0x17, 0x6e, 0x86, 0x42, 0xe1, 0xb4, 0x82, 0xaf, 0x95, 0x84, 0xcd, 0x1e, 0xc8, 0x3b, - 0x90, 0x68, 0xb5, 0xd5, 0x6e, 0x67, 0xe0, 0xcc, 0x25, 0xe8, 0xb2, 0x37, 0x82, 0x53, 0xca, 0x1b, - 0x5b, 0x9d, 0x81, 0x53, 0x02, 0x74, 0x12, 0xf6, 0xac, 0x4c, 0xb6, 0xda, 0xf8, 0x97, 0x7b, 0xc1, - 0xdf, 0x4b, 0x00, 0x9e, 0x6c, 0x64, 0x05, 0x32, 0xf6, 0xe9, 0xb2, 0xaa, 0xdb, 0xaa, 0xd5, 0x6e, - 0x0f, 0x0c, 0x87, 0xba, 0x40, 0xa6, 0x94, 0x1d, 0x9e, 0xcf, 0xa7, 0x94, 0xd3, 0xe5, 0x8a, 0xd2, - 0xa0, 0xb0, 0x92, 0xb2, 0x4f, 0x97, 0x2b, 0x36, 0x1b, 0x90, 0x6f, 0xc3, 0xa4, 0x7d, 0x5a, 0x50, - 0x75, 0xb7, 0x30, 0xbf, 0x1e, 0xda, 0xbc, 0xe6, 0x68, 0x8a, 0xe6, 0x18, 0x35, 0x53, 0x37, 0x4e, - 0x4b, 0x53, 0x68, 0x1b, 0xe5, 0xb4, 0x50, 0x51, 0x94, 0xb8, 0x7d, 0x5a, 0xa8, 0xd8, 0xe4, 0x36, - 0x24, 0xac, 0xbe, 0xa3, 0x9a, 0xc6, 0x01, 0x4b, 0xd4, 0x4c, 0xde, 0x46, 0xdf, 0xa9, 0x1b, 0x07, - 0xca, 0xa4, 0x45, 0xff, 0x72, 0x79, 0x7b, 0xc0, 0xf7, 0x41, 0x16, 0x21, 0x76, 0x51, 0xde, 0x60, - 0x54, 0x34, 0x6f, 0x50, 0x3a, 0x42, 0x20, 0xd6, 0x66, 0x15, 0x23, 0x7a, 0x27, 0xa3, 0xd0, 0x67, - 0x72, 0x0b, 0x92, 0xad, 0x43, 0xb5, 0xa7, 0x0d, 0x8e, 0x06, 0x73, 0xd1, 0x37, 0xa2, 0x77, 0x92, - 0x4a, 0xa2, 0x75, 0xb8, 0x8d, 0x43, 0xbe, 0xdc, 0x63, 0x48, 0x6f, 0x59, 0x8a, 0xe6, 0x6e, 0x00, - 0xc3, 0x63, 0x5f, 0x33, 0xf5, 0x93, 0x8e, 0xee, 0x1c, 0x32, 0xdd, 0x28, 0x1e, 0x40, 0xbe, 0x02, - 0xf2, 0xa0, 0x6f, 0x1b, 0x1a, 0x96, 0x12, 0xb5, 0xad, 0xb5, 0x1c, 0x7e, 0x56, 0xc9, 0x28, 0xd9, - 0x11, 0xbe, 0x41, 0xe1, 0x85, 0x3b, 0x90, 0xda, 0x68, 0x3e, 0x1c, 0xf1, 0xbd, 0x05, 0xc9, 0xfd, - 0x8e, 0xa3, 0xda, 0x9a, 0x63, 0x70, 0xb6, 0x89, 0xfd, 0x8e, 0x83, 0xaf, 0x16, 0x7e, 0x28, 0x41, - 0x72, 0x44, 0xf7, 0x0d, 0x88, 0xe1, 0x1e, 0xf9, 0x29, 0xe6, 0xb5, 0xe0, 0xa6, 0x45, 0x59, 0x4b, - 0xc9, 0xe1, 0xf9, 0x7c, 0x0c, 0x91, 0xcd, 0x88, 0x42, 0x67, 0x91, 0x75, 0x88, 0xb6, 0x07, 0x47, - 0xbc, 0xa2, 0x7f, 0x29, 0x54, 0xd1, 0x3d, 0x79, 0x58, 0xcd, 0xdd, 0x68, 0x3e, 0xdc, 0x8c, 0x28, - 0x38, 0xa5, 0x94, 0x06, 0xe8, 0x59, 0xfa, 0x71, 0x57, 0x73, 0x3a, 0x96, 0xb9, 0xf0, 0x57, 0x31, - 0x80, 0xdd, 0xd3, 0x91, 0xd3, 0xbc, 0x03, 0x53, 0xba, 0xe6, 0x68, 0x9e, 0xf4, 0xa9, 0xc2, 0xdc, - 0xcb, 0x5c, 0xa0, 0x14, 0x43, 0xef, 0x57, 0x92, 0xba, 0xbb, 0xa3, 0x2a, 0x64, 0x47, 0x93, 0xd5, - 0x0e, 0x3a, 0xc8, 0x95, 0xbc, 0x48, 0xc9, 0xe8, 0xe2, 0x90, 0xcc, 0x43, 0xaa, 0x65, 0x51, 0xbd, - 0x53, 0x29, 0xd0, 0x8d, 0xa6, 0x14, 0x60, 0x90, 0x6b, 0xb9, 0x36, 0x3d, 0xe1, 0x9a, 0xad, 0x33, - 0x9a, 0x00, 0x62, 0x8a, 0x07, 0xa0, 0xfe, 0x9d, 0x53, 0xb5, 0x6f, 0x9d, 0x18, 0x36, 0x8d, 0xe0, - 0xb8, 0x92, 0x70, 0x4e, 0x77, 0x70, 0x48, 0xee, 0xc3, 0x4c, 0xc7, 0x7c, 0x66, 0xd8, 0x8e, 0xda, - 0xb7, 0xba, 0x9a, 0xdd, 0xf9, 0x63, 0xaa, 0x03, 0x1a, 0xa3, 0x49, 0x85, 0xb0, 0x57, 0x3b, 0xc2, - 0x1b, 0xf2, 0x0e, 0x5c, 0x3f, 0xd0, 0x1c, 0xe3, 0x44, 0x3b, 0x53, 0x5b, 0x87, 0x9a, 0x69, 0x1a, - 0x5d, 0xbe, 0xaf, 0x84, 0xff, 0x10, 0x39, 0xc3, 0xa9, 0xca, 0x8c, 0x88, 0xed, 0xe3, 0x6d, 0x98, - 0xd5, 0x8d, 0x67, 0x9d, 0x96, 0x11, 0x98, 0x9b, 0xf4, 0xcf, 0x25, 0x8c, 0xc8, 0x37, 0xf5, 0x6b, - 0x00, 0x86, 0xa9, 0xed, 0x77, 0x0d, 0xb5, 0x65, 0xb7, 0xe6, 0xa6, 0xbc, 0x83, 0x51, 0x95, 0xa2, - 0x65, 0xa5, 0x8c, 0xa9, 0x9c, 0x3e, 0xda, 0x2d, 0xd4, 0xc7, 0xa8, 0x0f, 0x9b, 0x03, 0xe6, 0xc9, - 0x23, 0x80, 0xac, 0x42, 0x0c, 0x07, 0x73, 0x29, 0x9e, 0xcd, 0x82, 0xa7, 0xd3, 0x5d, 0x97, 0xb2, - 0x14, 0xfb, 0xe1, 0x6f, 0xf0, 0xbc, 0x8c, 0xd4, 0x3c, 0x66, 0xfe, 0x5c, 0x82, 0x5b, 0xef, 0xb2, - 0xad, 0x15, 0x4d, 0xc7, 0x30, 0x4d, 0xad, 0xe6, 0x75, 0x73, 0xd8, 0x6b, 0xb9, 0xda, 0xe9, 0xe8, - 0x03, 0xee, 0x2e, 0xa1, 0x9e, 0x88, 0xcf, 0x17, 0x26, 0x8a, 0x69, 0xf3, 0xc0, 0x7d, 0x3b, 0x20, - 0xb7, 0x21, 0xa3, 0xb1, 0x45, 0x04, 0xe7, 0xc9, 0x28, 0x69, 0x0e, 0x52, 0xcd, 0x2c, 0xd8, 0x90, - 0xda, 0xeb, 0x77, 0x3b, 0xe6, 0xd1, 0xae, 0x75, 0x64, 0x98, 0xa4, 0x0a, 0x51, 0x6f, 0xe9, 0xaf, - 0xbc, 0x64, 0xe9, 0xb0, 0xe8, 0x82, 0x04, 0x38, 0xdf, 0xaf, 0xc1, 0x89, 0x80, 0x06, 0x17, 0xfe, - 0x04, 0xd2, 0x15, 0xeb, 0xc4, 0xc4, 0x55, 0x77, 0x34, 0xe7, 0x90, 0xdc, 0x86, 0xf4, 0x31, 0x95, - 0x41, 0x75, 0x50, 0x08, 0x56, 0x5b, 0x37, 0x23, 0x4a, 0xea, 0x58, 0x90, 0xac, 0x08, 0xf1, 0x76, - 0xe7, 0xd4, 0xd0, 0x79, 0x88, 0x5e, 0x5d, 0xb6, 0xcd, 0x88, 0xc2, 0x66, 0x96, 0x26, 0x21, 0xd6, - 0xd7, 0x9c, 0xc3, 0x85, 0xff, 0x8c, 0xc1, 0xd4, 0xee, 0x29, 0x3f, 0x72, 0x61, 0xeb, 0x44, 0x0f, - 0xb2, 0x2f, 0xeb, 0xb3, 0xca, 0xf8, 0x52, 0x61, 0x34, 0xa4, 0x0c, 0xd3, 0x3a, 0x17, 0x5d, 0x45, - 0x5e, 0x03, 0x9a, 0x33, 0xc7, 0xa4, 0x1b, 0x71, 0x83, 0x4a, 0x46, 0x17, 0x46, 0x03, 0xb2, 0x0a, - 0x53, 0xb4, 0x92, 0xd0, 0x82, 0x16, 0xbd, 0xb8, 0xa0, 0x25, 0xb1, 0x9a, 0xd0, 0x8a, 0xb6, 0x05, - 0x33, 0x74, 0x56, 0x20, 0x23, 0xc4, 0xae, 0x92, 0x11, 0x64, 0xe4, 0xe2, 0x4b, 0x0a, 0xb7, 0x59, - 0x35, 0xf3, 0xe2, 0x3e, 0x4e, 0xe3, 0x3e, 0x6d, 0x9f, 0x2e, 0x6f, 0x8c, 0x42, 0x9f, 0x2e, 0x59, - 0x08, 0x2d, 0x39, 0x79, 0xc5, 0x25, 0x0b, 0x63, 0x96, 0x2c, 0x08, 0x4b, 0x26, 0xdc, 0x25, 0x0b, - 0xde, 0x92, 0xdf, 0x82, 0x64, 0xdf, 0xee, 0x58, 0x76, 0xc7, 0x39, 0xa3, 0x81, 0x3d, 0x1d, 0x0e, - 0x80, 0xdd, 0xd3, 0x66, 0xeb, 0xd0, 0xd0, 0x8f, 0xbb, 0xc6, 0x0e, 0xa7, 0x54, 0x46, 0x73, 0x48, - 0x15, 0x32, 0xda, 0xfe, 0xc0, 0xea, 0x1e, 0x3b, 0x86, 0x4a, 0xc3, 0x74, 0xea, 0x8a, 0x61, 0x9a, - 0x76, 0xa7, 0xe1, 0x0b, 0xb2, 0x02, 0x49, 0x4d, 0x7f, 0xa6, 0x99, 0x2d, 0x43, 0x9f, 0x6b, 0x5d, - 0xdc, 0x86, 0x8e, 0x08, 0x79, 0x8c, 0xff, 0xf7, 0x12, 0xed, 0xae, 0xcb, 0x56, 0xaf, 0xa7, 0x99, - 0x3a, 0xf9, 0x36, 0x44, 0x5b, 0x1d, 0x9d, 0x3b, 0xd7, 0x9b, 0x63, 0x2e, 0x4e, 0x38, 0xa1, 0xe7, - 0xb1, 0xac, 0xc2, 0x94, 0x6b, 0x15, 0x05, 0x67, 0x92, 0x2f, 0x43, 0xca, 0xd6, 0x4e, 0x46, 0x4d, - 0xf1, 0x04, 0x0f, 0x0e, 0xb0, 0xb5, 0x13, 0xf7, 0x64, 0x5a, 0x82, 0x29, 0xdb, 0x18, 0xe0, 0xf1, - 0xd0, 0x74, 0xaf, 0x68, 0x6e, 0xbf, 0x7c, 0xa5, 0x45, 0x05, 0x69, 0x6b, 0xa6, 0xbe, 0x19, 0x51, - 0x92, 0x36, 0x7f, 0x26, 0x55, 0x3c, 0x18, 0x23, 0x8f, 0x96, 0x65, 0xb6, 0x79, 0xeb, 0xfd, 0xe6, - 0x65, 0x4c, 0xca, 0x96, 0xd9, 0xde, 0x8c, 0x28, 0x6c, 0x75, 0x1c, 0x90, 0x06, 0x4c, 0xd3, 0xe0, - 0x68, 0x1d, 0x1a, 0xad, 0x23, 0x55, 0x33, 0xdd, 0x53, 0xdf, 0xff, 0xbf, 0x80, 0xd5, 0x56, 0xc7, - 0x3c, 0x2a, 0x23, 0x7d, 0xd1, 0xc4, 0x68, 0x4d, 0x77, 0x85, 0x31, 0x79, 0x02, 0x74, 0xac, 0x62, - 0x67, 0x8b, 0x67, 0x14, 0x76, 0xf5, 0xf2, 0xff, 0x2e, 0x61, 0x87, 0x3d, 0xb1, 0xf1, 0x01, 0xbb, - 0x70, 0xf0, 0xc6, 0xa8, 0x36, 0x64, 0x56, 0xd4, 0x6d, 0x6c, 0x80, 0x45, 0xd6, 0x28, 0x69, 0xe2, - 0xaa, 0xac, 0x8b, 0xe6, 0xc0, 0xc7, 0x9a, 0xc9, 0xed, 0xb2, 0x46, 0xa9, 0x1b, 0x30, 0xad, 0x1f, - 0x3b, 0x67, 0x6a, 0xeb, 0xac, 0xd5, 0x35, 0xa8, 0xdc, 0xc9, 0x4b, 0xd5, 0x50, 0x39, 0x76, 0xce, - 0xca, 0x48, 0xcf, 0x24, 0x4d, 0xeb, 0xc2, 0x98, 0x3c, 0x01, 0x62, 0x9f, 0xaa, 0x7d, 0xcd, 0xd6, - 0x7a, 0x78, 0xa0, 0x3e, 0xee, 0x53, 0xa6, 0xcc, 0xb9, 0xef, 0x5e, 0x64, 0xa6, 0xd3, 0x1d, 0x9c, - 0xd3, 0xc4, 0x29, 0x8c, 0x6f, 0xd6, 0xf6, 0x43, 0x63, 0x58, 0xa3, 0x32, 0xe0, 0x95, 0x58, 0x33, - 0x0d, 0xf8, 0x58, 0xbb, 0x6a, 0x30, 0x9e, 0xa9, 0x03, 0x47, 0x73, 0x8e, 0x07, 0x94, 0x6d, 0xea, - 0x72, 0x35, 0x18, 0xcf, 0x9a, 0x94, 0x9e, 0x7b, 0x83, 0x2e, 0x8c, 0x89, 0x02, 0x59, 0xd3, 0x38, - 0x19, 0x1d, 0x00, 0x50, 0x07, 0x69, 0xca, 0xf1, 0xce, 0x05, 0x1c, 0xeb, 0xc6, 0x09, 0x3f, 0x0d, - 0x30, 0x0d, 0x64, 0x4c, 0x11, 0x08, 0xf2, 0x44, 0x29, 0x33, 0xaf, 0xc0, 0x93, 0x89, 0x29, 0xf0, - 0x44, 0x39, 0x35, 0x98, 0xd6, 0xbb, 0x3e, 0x31, 0xa7, 0x2f, 0xdf, 0xf8, 0x96, 0x27, 0x54, 0x49, - 0x1e, 0x9e, 0xcf, 0xa7, 0x45, 0x84, 0xaa, 0xa2, 0x2b, 0x88, 0xed, 0x5f, 0x02, 0xa5, 0xce, 0x5e, - 0x7d, 0x09, 0xf4, 0x60, 0xff, 0x12, 0xae, 0xb6, 0xbb, 0xc2, 0x2e, 0xbe, 0x8f, 0xf9, 0x1f, 0xd3, - 0x28, 0x1e, 0x1e, 0x3d, 0xaf, 0x93, 0xe9, 0x3a, 0x5f, 0xbd, 0xd0, 0x35, 0x76, 0xe9, 0x24, 0xc1, - 0xed, 0x64, 0x3b, 0x80, 0xa1, 0xdf, 0x39, 0x61, 0x97, 0xbe, 0x76, 0xa9, 0xdf, 0xed, 0x86, 0x5d, - 0xda, 0x09, 0xb8, 0x34, 0x4d, 0x88, 0x47, 0xc6, 0x19, 0x4d, 0x88, 0xe4, 0x0a, 0x09, 0xf1, 0xc8, - 0x38, 0x1b, 0x25, 0x44, 0xf6, 0xcc, 0x12, 0x22, 0xf2, 0xa0, 0x09, 0x71, 0xe6, 0x0a, 0x09, 0xf1, - 0xc8, 0x38, 0xf3, 0x12, 0x22, 0x1f, 0x10, 0x1b, 0x66, 0x30, 0xbf, 0x04, 0xb7, 0x39, 0x7b, 0xa9, - 0x0e, 0x8b, 0x15, 0xc5, 0xb7, 0xa9, 0xd2, 0xec, 0xf0, 0x7c, 0x5e, 0x0e, 0xa2, 0xa8, 0x59, 0x4d, - 0xb7, 0xfd, 0xdb, 0x57, 0x20, 0xcb, 0x4f, 0xca, 0x58, 0x02, 0xa9, 0x6f, 0x5c, 0xbf, 0xd4, 0xa3, - 0x2b, 0x74, 0x06, 0x56, 0x3f, 0xee, 0xd1, 0xba, 0x08, 0x90, 0x3d, 0x90, 0xdb, 0x96, 0xdd, 0xc2, - 0x64, 0xe6, 0x5e, 0x89, 0xcf, 0xdd, 0x18, 0x7f, 0x14, 0x13, 0x98, 0x6e, 0xe0, 0x94, 0xd1, 0x15, - 0xd7, 0x66, 0x44, 0x99, 0x6e, 0xfb, 0x10, 0x62, 0x8c, 0xee, 0xd8, 0x83, 0x1a, 0xba, 0x49, 0x99, - 0x2f, 0x5e, 0xa8, 0x71, 0x9c, 0x18, 0x54, 0xc7, 0x8c, 0x1d, 0x86, 0x5f, 0xb2, 0x0c, 0x2a, 0x66, - 0xee, 0x95, 0x97, 0x61, 0xea, 0x09, 0x2d, 0xc3, 0x8a, 0x15, 0xe9, 0xd3, 0x58, 0xe9, 0x5a, 0x58, - 0x8c, 0xdb, 0x16, 0xdd, 0xc9, 0xad, 0x4b, 0x5d, 0x7a, 0x07, 0xe3, 0xa2, 0x6b, 0x39, 0x35, 0xb3, - 0x6d, 0x71, 0x97, 0xee, 0xfb, 0x21, 0xb2, 0x0f, 0xd7, 0x3d, 0xd6, 0x62, 0x62, 0xc9, 0x51, 0xee, - 0xf7, 0xae, 0xc0, 0xdd, 0x97, 0x4c, 0x48, 0x3f, 0x84, 0x8e, 0x5f, 0x03, 0x95, 0xf4, 0xa5, 0x57, - 0x5d, 0x83, 0xe9, 0x28, 0xb8, 0x06, 0xaa, 0xe8, 0x7d, 0xb8, 0xb6, 0x6f, 0x68, 0x2d, 0xcb, 0x74, - 0xf3, 0x0a, 0xf2, 0x7f, 0xed, 0x52, 0x0d, 0x95, 0xe8, 0x1c, 0x96, 0x41, 0x78, 0xb1, 0xd9, 0xf7, - 0x43, 0xe8, 0xf5, 0x9c, 0x33, 0x1e, 0x31, 0xa9, 0x6e, 0x5e, 0xbf, 0xd4, 0xeb, 0x19, 0x5f, 0x3c, - 0x7f, 0xf2, 0xda, 0xb0, 0x2f, 0x02, 0x41, 0x9e, 0x28, 0x6b, 0xfe, 0x15, 0x78, 0xf2, 0x48, 0xda, - 0x17, 0x01, 0x21, 0x3a, 0x7b, 0x96, 0x4e, 0xcf, 0xd4, 0x73, 0xf3, 0x57, 0x8c, 0xce, 0x6d, 0x4b, - 0x37, 0x58, 0x9e, 0xe2, 0xd1, 0xc9, 0x01, 0x8c, 0x4e, 0x91, 0x27, 0x4d, 0x59, 0x6f, 0x5c, 0x1a, - 0x9d, 0x1e, 0x53, 0x9e, 0xb7, 0xa6, 0x75, 0x1f, 0x92, 0xdb, 0x80, 0xa4, 0x7b, 0x58, 0x24, 0x5f, - 0x87, 0x4c, 0xaf, 0x63, 0x5a, 0xb6, 0xfa, 0xcc, 0xb0, 0x07, 0xd8, 0xe6, 0xbf, 0xec, 0xbb, 0x14, - 0x12, 0x29, 0x69, 0x4a, 0xfb, 0x88, 0x91, 0xe6, 0xde, 0x85, 0xa9, 0xd1, 0x79, 0xf1, 0x73, 0x31, - 0x7a, 0x08, 0x69, 0xf1, 0xb4, 0x48, 0x6e, 0xc0, 0x64, 0x4f, 0xb3, 0x0f, 0x3a, 0x26, 0xbf, 0x1a, - 0xe2, 0x23, 0xec, 0x35, 0x46, 0x17, 0x0d, 0xd6, 0xb1, 0xe9, 0xb8, 0xbd, 0xaf, 0x7b, 0xaf, 0x80, - 0x58, 0xee, 0x7f, 0x25, 0x10, 0x0e, 0x87, 0xe3, 0xae, 0x5b, 0xa4, 0xcf, 0x70, 0xdd, 0xf2, 0x26, - 0x4c, 0xbb, 0xf7, 0x25, 0xfe, 0xbe, 0x9b, 0xdf, 0x9a, 0x30, 0xaa, 0x2f, 0x43, 0xda, 0x0d, 0xb0, - 0x9e, 0x36, 0x38, 0xe2, 0x57, 0x6c, 0x29, 0x8e, 0x6d, 0x6b, 0x83, 0x23, 0xb2, 0x04, 0xb3, 0x22, - 0x09, 0x1a, 0xd5, 0xb1, 0xad, 0x2e, 0xbf, 0xb4, 0x26, 0x02, 0x69, 0x99, 0xbd, 0x21, 0xb7, 0x20, - 0x69, 0xee, 0xab, 0x8e, 0x8d, 0x6e, 0x3a, 0xc9, 0xae, 0xca, 0xcc, 0xfd, 0x5d, 0x1c, 0xbe, 0x17, - 0x4b, 0xc6, 0xe4, 0x78, 0xee, 0x2f, 0xbc, 0x1d, 0xa3, 0xf6, 0xee, 0x80, 0xec, 0x5b, 0x41, 0x6b, - 0x1d, 0xb1, 0x0f, 0x4b, 0xca, 0xb4, 0xc0, 0xbd, 0xd8, 0x3a, 0x22, 0xf7, 0x60, 0x26, 0xa0, 0x1b, - 0x4a, 0x4c, 0x3f, 0x31, 0x29, 0xb2, 0x4f, 0x01, 0x48, 0xfe, 0x55, 0x56, 0xda, 0x3d, 0x1d, 0xa8, - 0xde, 0x97, 0xa6, 0xac, 0xa8, 0x87, 0x62, 0xeb, 0x28, 0xf7, 0x04, 0xd2, 0xe2, 0xd1, 0x97, 0xd4, - 0x60, 0xba, 0xa7, 0x9d, 0xaa, 0xde, 0xf9, 0x99, 0x9b, 0x21, 0x54, 0xc1, 0x8b, 0x07, 0x07, 0xb6, - 0x81, 0x16, 0xd5, 0xbd, 0xf9, 0xe9, 0x9e, 0x76, 0x3a, 0x1a, 0xe5, 0xfe, 0x49, 0x82, 0x6c, 0xe0, - 0x04, 0xfc, 0xb2, 0xa6, 0x56, 0xfa, 0x6c, 0x4d, 0xed, 0x7d, 0x98, 0xf5, 0x77, 0xe5, 0xfc, 0x72, - 0x98, 0xd9, 0xfc, 0x9a, 0xd0, 0x77, 0xf3, 0x1b, 0xe1, 0x50, 0x17, 0x1c, 0x0d, 0x77, 0xc1, 0xb9, - 0xbf, 0x0b, 0xc8, 0x8d, 0xc6, 0x5a, 0x85, 0x9b, 0x63, 0xe4, 0x16, 0x6c, 0x36, 0x13, 0x14, 0x0e, - 0x2d, 0xb1, 0x06, 0x73, 0xe3, 0xe4, 0x13, 0xac, 0x37, 0x1b, 0x92, 0x11, 0xe7, 0xdd, 0x85, 0x6b, - 0x3e, 0x31, 0x45, 0x03, 0x8a, 0xa2, 0xa2, 0x01, 0xbf, 0x03, 0x69, 0xf1, 0xd0, 0x4e, 0xe6, 0x20, - 0xb1, 0xaf, 0x39, 0x8e, 0x61, 0x9f, 0x8d, 0x2e, 0x6c, 0xd9, 0x50, 0x08, 0xd7, 0x09, 0x7a, 0x93, - 0xc8, 0x47, 0xb9, 0xff, 0x91, 0x20, 0xe3, 0x3b, 0xa5, 0xa3, 0x9a, 0xfc, 0xb7, 0x7c, 0x8c, 0x93, - 0x1b, 0x34, 0x4c, 0xf9, 0xbe, 0x8b, 0xcb, 0x89, 0xe0, 0xc5, 0xe5, 0x16, 0xcc, 0xf4, 0x3a, 0x66, - 0xc8, 0xd0, 0xd1, 0x2b, 0x19, 0xba, 0xd7, 0x31, 0xfd, 0x86, 0x46, 0x6e, 0xe8, 0x95, 0x9f, 0xe9, - 0xfa, 0x05, 0x9d, 0x52, 0x44, 0x72, 0xef, 0x8b, 0xfb, 0x45, 0x9d, 0xdd, 0x86, 0x8c, 0x5f, 0xd7, - 0xcc, 0xa6, 0xe9, 0xb6, 0xa0, 0x68, 0xb2, 0x00, 0x19, 0x6f, 0x7d, 0xcf, 0x82, 0x29, 0x37, 0xfe, - 0xd0, 0x18, 0xdf, 0x05, 0x5f, 0xdb, 0xf0, 0x05, 0x28, 0x32, 0xa7, 0x82, 0xaf, 0x4d, 0x40, 0xdf, - 0xf0, 0xb1, 0x14, 0xe4, 0xcd, 0x8a, 0x6c, 0x51, 0xe4, 0xd0, 0xbe, 0x26, 0xc2, 0xfb, 0xca, 0x15, - 0x41, 0x0e, 0x76, 0x0c, 0xe4, 0x1e, 0xc4, 0xd9, 0x05, 0x99, 0x74, 0xf1, 0x05, 0x19, 0xa3, 0xca, - 0xfd, 0x8b, 0x04, 0xd9, 0x40, 0x63, 0x40, 0x14, 0x96, 0x48, 0x8c, 0x8e, 0xdd, 0xf7, 0x05, 0x79, - 0xf8, 0x0b, 0x14, 0xad, 0x7a, 0xd5, 0x9a, 0xb2, 0xc3, 0x9a, 0xa2, 0x6d, 0xed, 0x14, 0x07, 0xcc, - 0x78, 0x98, 0x51, 0xaa, 0x1d, 0xbb, 0xcf, 0x34, 0x75, 0x17, 0xae, 0xf1, 0xbb, 0x4a, 0xfd, 0xc4, - 0xe8, 0x76, 0xd9, 0x1d, 0x13, 0xdb, 0x53, 0x96, 0xbd, 0xa8, 0x20, 0x4e, 0x2f, 0x91, 0x16, 0x61, - 0x66, 0x74, 0x59, 0x28, 0x50, 0xb3, 0x28, 0xba, 0xe6, 0xbe, 0x1a, 0xd1, 0xb3, 0x6a, 0xcb, 0xbb, - 0x8f, 0xcf, 0x5d, 0x6d, 0xdd, 0xfe, 0xe3, 0xf3, 0x30, 0xfa, 0x54, 0x82, 0x50, 0xc3, 0x41, 0x3e, - 0x80, 0x1b, 0xee, 0xaf, 0x0c, 0xba, 0x9d, 0x5e, 0xc7, 0x51, 0x8d, 0xd3, 0xbe, 0x65, 0x1a, 0xa6, - 0xf3, 0xd2, 0x34, 0x4d, 0x7f, 0x7c, 0xb0, 0x85, 0xb4, 0x55, 0x4e, 0x5a, 0xba, 0x39, 0x3c, 0x9f, - 0x9f, 0x19, 0xf3, 0x42, 0x99, 0x61, 0xbf, 0x4f, 0xf0, 0x81, 0xe2, 0x92, 0xd4, 0xda, 0xde, 0x92, - 0x13, 0x17, 0x2d, 0x49, 0x1d, 0x64, 0xdc, 0x92, 0xbe, 0x17, 0xee, 0x92, 0x3e, 0x30, 0x57, 0x83, - 0x8c, 0xaf, 0x21, 0x22, 0xeb, 0xfc, 0xda, 0x3f, 0x71, 0xe9, 0x7d, 0x22, 0xbd, 0x0b, 0xf7, 0xae, - 0xfe, 0x73, 0xbf, 0x93, 0x60, 0xda, 0xdf, 0x07, 0x91, 0xf9, 0xf0, 0xf7, 0xfd, 0x8c, 0xef, 0x1b, - 0xfe, 0x17, 0xf7, 0xe9, 0x07, 0x23, 0xc0, 0x36, 0x1c, 0xbb, 0x63, 0x0c, 0xd8, 0x0f, 0x4f, 0x14, - 0xe8, 0x69, 0xa7, 0x0a, 0x43, 0xc8, 0x36, 0x64, 0xfb, 0x86, 0xdd, 0xb1, 0x74, 0x4f, 0xa5, 0xb1, - 0xf1, 0x37, 0x95, 0xbc, 0x0b, 0xa2, 0xc4, 0x23, 0xd5, 0x4d, 0xf7, 0x7d, 0xe3, 0xdc, 0xc7, 0x12, - 0xcc, 0x8c, 0xe9, 0xca, 0xc8, 0x77, 0x81, 0xa0, 0x1c, 0xf4, 0x28, 0x76, 0xa9, 0xbf, 0x30, 0x06, - 0xf4, 0x88, 0x36, 0x5a, 0x08, 0x33, 0xa8, 0x0f, 0x21, 0x75, 0xb8, 0x86, 0x2c, 0x69, 0x83, 0x1b, - 0x70, 0x87, 0x85, 0x97, 0xfc, 0x50, 0xa2, 0xd3, 0x33, 0x46, 0x0c, 0xb3, 0x3d, 0xed, 0x54, 0x04, - 0x72, 0x9b, 0x61, 0xc9, 0xd1, 0xec, 0xcb, 0x70, 0x3d, 0xb4, 0x8c, 0x90, 0xef, 0x48, 0x80, 0x0d, - 0x66, 0xb3, 0x1a, 0x64, 0x03, 0xfd, 0x1c, 0x59, 0x83, 0x49, 0xa6, 0x29, 0xbe, 0xe7, 0x7c, 0x50, - 0x42, 0x77, 0x02, 0xd3, 0xaf, 0xc2, 0xa9, 0x73, 0x67, 0x40, 0xc2, 0xcd, 0x9b, 0x3f, 0x5b, 0x4b, - 0xc1, 0xb2, 0xf7, 0xc5, 0xb8, 0x4e, 0xee, 0x30, 0xb4, 0xf4, 0x95, 0xcb, 0xd4, 0xab, 0x1d, 0x16, - 0x73, 0x5b, 0x90, 0x0d, 0x74, 0x77, 0x64, 0x56, 0x4c, 0xfe, 0x19, 0x9e, 0xe3, 0xc3, 0xa5, 0x6c, - 0x22, 0x5c, 0xca, 0x72, 0xf7, 0x20, 0xe3, 0xeb, 0xe9, 0x2e, 0xd6, 0x56, 0x6e, 0x55, 0x24, 0xbf, - 0xea, 0x0e, 0x73, 0xdf, 0x70, 0xb3, 0x83, 0xdb, 0x7f, 0xbd, 0xca, 0x47, 0xa4, 0xdc, 0x37, 0x61, - 0xda, 0xdf, 0x79, 0xbd, 0xd2, 0xf4, 0xd2, 0x14, 0x24, 0xf8, 0xc7, 0x80, 0xbb, 0x3f, 0x91, 0x20, - 0x4e, 0x7f, 0x07, 0x48, 0x64, 0x48, 0xbf, 0xd7, 0xa8, 0xd5, 0x55, 0xa5, 0xfa, 0xdd, 0xbd, 0x6a, - 0x73, 0x57, 0x8e, 0x90, 0x2c, 0xa4, 0x28, 0x52, 0x2c, 0x97, 0xab, 0x3b, 0xbb, 0xb2, 0x44, 0x08, - 0x4c, 0xef, 0xd5, 0xcb, 0x8d, 0xfa, 0x46, 0x4d, 0xd9, 0xae, 0x56, 0xd4, 0xbd, 0x1d, 0x79, 0x82, - 0xcc, 0x82, 0x2c, 0x62, 0x95, 0xc6, 0xe3, 0xba, 0x1c, 0x45, 0x66, 0x3e, 0xba, 0x18, 0xce, 0x0d, - 0x50, 0xc5, 0x11, 0x53, 0xaa, 0xbe, 0x45, 0x27, 0x71, 0xd1, 0x1d, 0xa5, 0xb1, 0xa3, 0xd4, 0xaa, - 0xbb, 0x45, 0xe5, 0x89, 0x9c, 0xb8, 0x7b, 0x13, 0xe2, 0xf4, 0xb7, 0x87, 0x64, 0x1a, 0x60, 0xab, - 0xa1, 0x14, 0x1f, 0x17, 0xeb, 0xaa, 0xb2, 0x2c, 0x47, 0xee, 0xb6, 0xe8, 0x57, 0x12, 0x5e, 0x69, - 0x70, 0xde, 0x76, 0xb1, 0xac, 0xee, 0xd5, 0x1f, 0xd6, 0x91, 0x79, 0x84, 0xa4, 0x21, 0x89, 0xc0, - 0xa3, 0x65, 0x75, 0x49, 0x96, 0x70, 0xb2, 0x3b, 0x52, 0x97, 0xe5, 0x09, 0xdf, 0xb8, 0x20, 0x47, - 0x05, 0xea, 0x65, 0x39, 0x96, 0x4b, 0x7e, 0xf4, 0x37, 0xf9, 0xc8, 0xcf, 0xff, 0x36, 0x1f, 0xb9, - 0xfb, 0x63, 0x09, 0x60, 0x67, 0xf3, 0x89, 0xb0, 0xca, 0xce, 0xe6, 0x13, 0xff, 0x2a, 0x08, 0x78, - 0xab, 0xb8, 0x23, 0xba, 0xca, 0x2c, 0xc8, 0xa3, 0x71, 0x41, 0x55, 0xaa, 0x8f, 0xd4, 0xa2, 0x1c, - 0x1d, 0x83, 0x96, 0x98, 0x82, 0x38, 0xba, 0xcc, 0x29, 0xe3, 0x21, 0xac, 0x24, 0x4f, 0x0a, 0xb2, - 0xfd, 0xc3, 0x04, 0x64, 0xfc, 0x47, 0xcc, 0x2c, 0xa4, 0x2a, 0xc5, 0xdd, 0xa2, 0xaa, 0x14, 0x77, - 0xab, 0xea, 0x12, 0x33, 0xa1, 0x07, 0x2c, 0xcb, 0x92, 0x1f, 0x28, 0xc8, 0x13, 0x7e, 0x60, 0x45, - 0x8e, 0xfa, 0x81, 0x55, 0x39, 0xe6, 0x07, 0x1e, 0xc8, 0x71, 0x3f, 0xb0, 0xc6, 0x6c, 0xe6, 0x01, - 0x6f, 0xc9, 0x09, 0x3f, 0xb0, 0x2e, 0x27, 0xfd, 0xc0, 0xdb, 0xf2, 0x14, 0x3a, 0x88, 0x20, 0xd8, - 0x92, 0x0c, 0x01, 0x64, 0x59, 0x4e, 0x05, 0x90, 0x82, 0x9c, 0x0e, 0x20, 0x2b, 0x72, 0x26, 0x80, - 0xac, 0xca, 0xd3, 0x01, 0xe4, 0x81, 0x9c, 0x15, 0x34, 0xb6, 0x04, 0xe0, 0xfd, 0xe4, 0x8d, 0xa4, - 0x20, 0x51, 0x6e, 0xd4, 0x77, 0xab, 0xef, 0xa3, 0xb3, 0xa7, 0x20, 0xd1, 0xac, 0x36, 0x9b, 0xb5, - 0x46, 0x5d, 0x96, 0x48, 0x12, 0x62, 0x0f, 0xab, 0x4f, 0x9a, 0xf2, 0x04, 0xce, 0xf0, 0x7e, 0xec, - 0x82, 0xdb, 0xd8, 0xa0, 0xae, 0x5a, 0x2f, 0xd7, 0xaa, 0x4d, 0x39, 0x42, 0xae, 0x41, 0xa6, 0xbc, - 0x59, 0xac, 0xd7, 0xab, 0x5b, 0xea, 0x76, 0xb1, 0xf9, 0xb0, 0x29, 0x4b, 0x77, 0x57, 0x21, 0x4e, - 0x83, 0x8d, 0xb2, 0xdf, 0x2a, 0x36, 0x9b, 0x6a, 0x91, 0xb1, 0x67, 0x83, 0x92, 0x2c, 0x79, 0x83, - 0xb2, 0x3c, 0x91, 0x8b, 0xa1, 0x74, 0x77, 0xfb, 0x40, 0xc2, 0x5f, 0x25, 0x09, 0xc0, 0xe4, 0x56, - 0xe3, 0x31, 0x8b, 0xc6, 0x04, 0x44, 0xb7, 0x1a, 0x8f, 0x65, 0x09, 0x37, 0x58, 0xaa, 0x6e, 0x35, - 0x1e, 0xab, 0xf5, 0x86, 0xb2, 0x5d, 0xdc, 0x92, 0x27, 0x90, 0x8c, 0x3f, 0xd3, 0xc8, 0x2b, 0x96, - 0x1a, 0x8f, 0xaa, 0xee, 0xdb, 0x18, 0x6e, 0x66, 0xb3, 0xf6, 0xee, 0xa6, 0x1c, 0xc7, 0x75, 0xf1, - 0x89, 0x06, 0xda, 0xdd, 0xff, 0x8a, 0xc2, 0xec, 0xb8, 0x8f, 0x87, 0x24, 0x03, 0x53, 0xe5, 0x5a, - 0x45, 0x55, 0x36, 0xf6, 0xa8, 0x0b, 0xb9, 0xc3, 0x6a, 0xb3, 0xca, 0x73, 0x00, 0x0e, 0xb7, 0x6a, - 0xf5, 0x87, 0x6a, 0x79, 0xb3, 0x5a, 0x7e, 0x28, 0x4f, 0xd0, 0x68, 0x77, 0xb1, 0x62, 0x45, 0x91, - 0xa3, 0x2e, 0x55, 0x65, 0x6f, 0xf7, 0x89, 0x5a, 0x7e, 0x52, 0xde, 0xaa, 0xca, 0x31, 0x72, 0x03, - 0x08, 0x65, 0xf4, 0xbe, 0xba, 0x53, 0x54, 0x8a, 0xdb, 0x6a, 0xb3, 0xba, 0xbb, 0xb7, 0xc3, 0x9c, - 0x9c, 0xd2, 0x56, 0x1f, 0xa9, 0xcd, 0xdd, 0xe2, 0xee, 0x5e, 0x53, 0x9e, 0x24, 0x33, 0x90, 0x45, - 0xac, 0x5e, 0x7d, 0xac, 0x72, 0xfd, 0xca, 0x09, 0x72, 0x13, 0x66, 0x38, 0x83, 0xdd, 0xda, 0x76, - 0xad, 0xfe, 0x2e, 0xe7, 0x90, 0x74, 0x39, 0xef, 0xfa, 0x39, 0x4f, 0x8d, 0x38, 0x6f, 0x8d, 0x98, - 0x80, 0xb7, 0x9d, 0x87, 0xd5, 0x27, 0x72, 0xca, 0xe5, 0x59, 0xac, 0x28, 0xbe, 0xb9, 0x69, 0x57, - 0x82, 0x4a, 0xf5, 0x51, 0xad, 0x5c, 0xc5, 0x05, 0xab, 0x72, 0x06, 0x23, 0x17, 0xc1, 0x8d, 0x86, - 0x52, 0xae, 0xaa, 0x2c, 0x75, 0xc9, 0xd3, 0x24, 0x07, 0x37, 0x18, 0x4b, 0x9a, 0xca, 0x44, 0x36, - 0x59, 0x57, 0xb4, 0x1d, 0x2a, 0xee, 0x56, 0x63, 0x57, 0xad, 0xd5, 0x37, 0x1a, 0xb2, 0x4c, 0x6e, - 0xc1, 0x75, 0x3f, 0xee, 0x4a, 0x78, 0x8d, 0x5c, 0x87, 0x6b, 0xf8, 0xaa, 0x54, 0x2d, 0x96, 0x1b, - 0x75, 0xbe, 0x55, 0x99, 0xb8, 0x02, 0x71, 0x18, 0xdd, 0x50, 0x9e, 0x09, 0x48, 0xb9, 0xdd, 0xa8, - 0x54, 0xe5, 0x37, 0xb8, 0x47, 0xfd, 0x6a, 0x02, 0x66, 0xc6, 0xdc, 0x6f, 0xd0, 0xf8, 0x18, 0x99, - 0x45, 0x5d, 0x96, 0x23, 0x01, 0xa4, 0xc0, 0x5c, 0x4c, 0x40, 0x56, 0x99, 0x89, 0x05, 0x64, 0x5d, - 0x8e, 0xa2, 0xeb, 0x8b, 0x7c, 0xd6, 0xe4, 0x58, 0x00, 0x5a, 0x29, 0xc8, 0xf1, 0x00, 0xb4, 0xb6, - 0x2a, 0x4f, 0xa2, 0x55, 0xc4, 0x89, 0x85, 0x75, 0x39, 0x11, 0xc0, 0x0a, 0x0f, 0xd6, 0xe4, 0x64, - 0x00, 0x7b, 0xb0, 0x5c, 0x90, 0xa7, 0x70, 0xbf, 0xe2, 0xdc, 0xa5, 0xc2, 0xaa, 0x0c, 0x01, 0xb0, - 0xb0, 0xb4, 0xba, 0x2e, 0xa7, 0x02, 0xe0, 0xea, 0xd2, 0xdb, 0x6b, 0xcc, 0xa8, 0xe2, 0x2e, 0x96, - 0xdf, 0x2e, 0x30, 0xa3, 0xfa, 0x36, 0xb2, 0xb2, 0x8e, 0x69, 0xc4, 0x8f, 0xae, 0x14, 0xde, 0x5a, - 0x5b, 0x97, 0xb3, 0x5c, 0xb5, 0xff, 0x28, 0xc1, 0xb4, 0xff, 0xbc, 0x85, 0xfb, 0xa4, 0xb6, 0xac, - 0x3e, 0xaa, 0x2a, 0x4f, 0xd4, 0x65, 0x9e, 0x1b, 0x04, 0xa8, 0xd0, 0x94, 0xa5, 0x00, 0xb4, 0xda, - 0x94, 0x27, 0x02, 0xd0, 0x7a, 0x93, 0x05, 0x8f, 0xc8, 0x6b, 0xad, 0xc9, 0xab, 0x83, 0x87, 0xad, - 0x14, 0x9a, 0xbc, 0x3a, 0x78, 0xd8, 0xda, 0x2a, 0x0f, 0x1c, 0x71, 0x6e, 0x61, 0xbd, 0x29, 0x27, - 0xb8, 0xd4, 0x7f, 0x16, 0x75, 0x0f, 0xa8, 0xfe, 0x73, 0xf0, 0x0c, 0x64, 0xb9, 0xeb, 0x96, 0x1b, - 0x7b, 0xf5, 0x5d, 0x34, 0x65, 0x24, 0x04, 0xae, 0xa0, 0x5b, 0x04, 0xc1, 0xb5, 0x55, 0x56, 0xe3, - 0xfc, 0xd3, 0x0b, 0xeb, 0xac, 0xc6, 0xf9, 0x50, 0x34, 0x69, 0x2c, 0x84, 0xa2, 0x51, 0xe3, 0xe8, - 0xf0, 0x7e, 0x0e, 0x68, 0xd6, 0xc9, 0x10, 0x4c, 0x0d, 0x9b, 0x08, 0xc1, 0xd4, 0xb4, 0xc9, 0x10, - 0x4c, 0x8d, 0x3b, 0x85, 0xf1, 0x17, 0xd8, 0x1c, 0x9a, 0x17, 0x42, 0x38, 0x33, 0x70, 0x2a, 0x84, - 0xaf, 0x3d, 0x78, 0xb0, 0x82, 0x9e, 0x73, 0x13, 0x66, 0xfc, 0x7c, 0x56, 0x96, 0x97, 0xde, 0x42, - 0xef, 0x09, 0xbe, 0x28, 0xac, 0x15, 0x96, 0x57, 0xd1, 0x81, 0x82, 0x2f, 0x1e, 0x14, 0x56, 0x0b, - 0xeb, 0x9e, 0x0f, 0x7d, 0x32, 0x01, 0x24, 0xdc, 0x55, 0xa0, 0x3b, 0xf0, 0x59, 0x98, 0x72, 0x68, - 0x02, 0x0e, 0x40, 0xcb, 0xcc, 0x8f, 0x44, 0xa8, 0xc0, 0xfc, 0x48, 0x84, 0x56, 0x58, 0x84, 0x8a, - 0xd0, 0x2a, 0x8b, 0x50, 0x11, 0x7a, 0xc0, 0x22, 0x54, 0x84, 0xb0, 0x9e, 0x07, 0x20, 0xac, 0xe8, - 0x01, 0x08, 0x6b, 0x7a, 0x00, 0x7a, 0x9b, 0x25, 0x5c, 0x9f, 0xa8, 0x58, 0xd7, 0x83, 0x18, 0x56, - 0xf6, 0x20, 0x86, 0xb5, 0x3d, 0x88, 0x61, 0x75, 0x0f, 0x62, 0xa8, 0xd7, 0x20, 0xf6, 0x60, 0xa4, - 0xd2, 0x7f, 0x95, 0xdc, 0x1f, 0xc3, 0xfb, 0x9b, 0x4c, 0xc1, 0x6f, 0x77, 0xaa, 0x4a, 0xad, 0x51, - 0xa1, 0x6a, 0x0d, 0x81, 0xcb, 0x3e, 0x0f, 0xe7, 0x20, 0xaa, 0x36, 0x04, 0xa2, 0x72, 0x43, 0x20, - 0xaa, 0x37, 0x04, 0xa2, 0x82, 0x43, 0xe0, 0x1a, 0x8b, 0x53, 0x3f, 0xf8, 0xd6, 0x28, 0x4e, 0xff, - 0x7d, 0x02, 0xc0, 0xbb, 0x4f, 0xa2, 0x19, 0x94, 0xa5, 0x77, 0x1c, 0xaa, 0xeb, 0x72, 0x84, 0x66, - 0x46, 0x01, 0x5a, 0x5e, 0x62, 0x75, 0xd9, 0x87, 0xa1, 0xe0, 0x41, 0x6c, 0x85, 0x25, 0x17, 0x1f, - 0xb6, 0xca, 0x92, 0x8b, 0x0f, 0x5b, 0x63, 0xc9, 0xc5, 0x87, 0xad, 0xf3, 0xcc, 0x2d, 0x60, 0x85, - 0x25, 0x9e, 0xb9, 0x45, 0x6c, 0x99, 0x67, 0x6e, 0x11, 0x5b, 0x65, 0xae, 0xe1, 0xc3, 0xd6, 0x98, - 0x6b, 0xf8, 0xb0, 0xb7, 0x98, 0x6b, 0xf8, 0xb0, 0xb7, 0x99, 0x6b, 0x88, 0xd8, 0xca, 0x12, 0x73, - 0x0d, 0x1f, 0xb6, 0xc2, 0x5c, 0xc3, 0x87, 0xad, 0x8d, 0x5c, 0xe3, 0xa3, 0x28, 0x8c, 0xbb, 0x2c, - 0x42, 0x33, 0x60, 0xe9, 0x2f, 0x96, 0x1f, 0xaa, 0x5b, 0xb5, 0xed, 0xda, 0x2e, 0xad, 0x87, 0x21, - 0x90, 0xe7, 0x3e, 0x3f, 0xb8, 0xca, 0x3c, 0xc3, 0x0f, 0xf2, 0xd4, 0x17, 0xe0, 0xc9, 0x53, 0x9f, - 0x1f, 0xa5, 0xe5, 0x31, 0x84, 0xae, 0xf1, 0xcc, 0x17, 0xe0, 0x50, 0xe0, 0x99, 0x2f, 0x20, 0xd7, - 0x03, 0x9e, 0xf9, 0xfc, 0x30, 0x2b, 0x95, 0x37, 0x80, 0x04, 0x98, 0xb0, 0x6a, 0x19, 0xc2, 0x79, - 0xc1, 0x0c, 0xe1, 0xbc, 0x66, 0x86, 0x70, 0x5e, 0x36, 0x6f, 0x52, 0x8d, 0xfa, 0xb6, 0xc9, 0x2a, - 0x67, 0xe8, 0x85, 0xbf, 0x78, 0x7a, 0xa6, 0xf0, 0xdd, 0x97, 0x89, 0xba, 0xac, 0x54, 0xb7, 0x8a, - 0x4f, 0x82, 0xa6, 0x60, 0x60, 0xc0, 0x14, 0x0c, 0x0c, 0x98, 0x82, 0x81, 0x01, 0x53, 0x70, 0x9e, - 0x01, 0x53, 0x30, 0x34, 0x68, 0x0a, 0x86, 0x06, 0x4d, 0xc1, 0x39, 0x04, 0x4d, 0xc1, 0xe5, 0x0a, - 0x9a, 0x82, 0xc1, 0x21, 0x53, 0x70, 0x26, 0x21, 0x53, 0x70, 0x2e, 0x21, 0x53, 0xf0, 0x0d, 0x86, - 0x4c, 0xc1, 0xf7, 0x18, 0x32, 0x85, 0xbb, 0xcd, 0x90, 0x29, 0xdc, 0x9d, 0x8a, 0xa6, 0xf8, 0xd1, - 0x04, 0x24, 0xf8, 0x2d, 0x38, 0xb6, 0xae, 0xca, 0xfb, 0x9c, 0x0a, 0xd3, 0xa3, 0x38, 0x5e, 0x66, - 0xad, 0xed, 0x68, 0x5c, 0x60, 0x0d, 0xf4, 0x68, 0x8c, 0x79, 0x45, 0x1c, 0x63, 0x4e, 0x11, 0xc7, - 0x98, 0x05, 0xc5, 0x31, 0x26, 0x40, 0x71, 0x8c, 0x05, 0x46, 0x1c, 0x63, 0x75, 0x11, 0xc7, 0x58, - 0x5a, 0xb2, 0x90, 0xf2, 0xe4, 0xc1, 0xba, 0xe2, 0x03, 0xb0, 0xa8, 0xf8, 0x00, 0xac, 0x28, 0x3e, - 0x00, 0xcb, 0x89, 0x0f, 0x40, 0xfd, 0xf8, 0x00, 0xaf, 0x90, 0xfc, 0x64, 0x02, 0xe2, 0xf4, 0x36, - 0x9b, 0xde, 0x2a, 0xd4, 0xea, 0x0d, 0x65, 0xd4, 0x0d, 0xa5, 0x20, 0xc1, 0x00, 0xde, 0x4c, 0x7b, - 0x6f, 0x79, 0x33, 0xed, 0x01, 0xbc, 0x99, 0xf6, 0x00, 0xde, 0x4c, 0x7b, 0x00, 0x6f, 0xa6, 0x3d, - 0x80, 0x37, 0xd3, 0x1e, 0xc0, 0x9b, 0x69, 0x0f, 0xe0, 0xcd, 0xb4, 0x07, 0xf0, 0x66, 0xda, 0x03, - 0xdc, 0x66, 0x5a, 0x40, 0x78, 0x33, 0x2d, 0x20, 0xbc, 0x99, 0x16, 0x10, 0xde, 0x4c, 0x0b, 0x08, - 0x6f, 0xa6, 0x05, 0x64, 0xa4, 0xa1, 0xd2, 0x5f, 0x4b, 0xbf, 0x7c, 0x9e, 0x97, 0x3e, 0x79, 0x9e, - 0x97, 0x7e, 0xf5, 0x3c, 0x1f, 0xf9, 0xed, 0xf3, 0x7c, 0xe4, 0x77, 0xcf, 0xf3, 0x91, 0xdf, 0x3f, - 0xcf, 0x47, 0x3e, 0x7d, 0x9e, 0x97, 0x3e, 0x1c, 0xe6, 0xa5, 0x8f, 0x86, 0xf9, 0xc8, 0xcf, 0x86, - 0x79, 0xe9, 0xe7, 0xc3, 0x7c, 0xe4, 0xe3, 0x61, 0x3e, 0xf2, 0x8b, 0x61, 0x3e, 0xf2, 0xcb, 0x61, - 0x5e, 0xfa, 0x64, 0x98, 0x97, 0x7e, 0x35, 0xcc, 0x47, 0x7e, 0x3b, 0xcc, 0x4b, 0xbf, 0x1b, 0xe6, - 0x23, 0xbf, 0x1f, 0xe6, 0xa5, 0x4f, 0x87, 0xf9, 0xc8, 0x87, 0x2f, 0xf2, 0x91, 0x8f, 0x5e, 0xe4, - 0xa5, 0x1f, 0xbe, 0xc8, 0x47, 0xfe, 0xf2, 0x45, 0x5e, 0xfa, 0xe9, 0x8b, 0x7c, 0xe4, 0x67, 0x2f, - 0xf2, 0x91, 0x9f, 0xbf, 0xc8, 0x4b, 0x1f, 0xbf, 0xc8, 0x4b, 0xbf, 0x78, 0x91, 0x97, 0xbe, 0xf7, - 0xb5, 0xab, 0xfe, 0x37, 0x91, 0x63, 0xf6, 0xf7, 0xf7, 0x27, 0xe9, 0xd5, 0xfa, 0xca, 0xff, 0x05, - 0x00, 0x00, 0xff, 0xff, 0x9a, 0x13, 0x20, 0x07, 0xda, 0x3d, 0x00, 0x00, + golang_proto.RegisterFile("lorawan-stack/api/lorawan.proto", fileDescriptor_lorawan_58aef822c5219cad) +} + +var fileDescriptor_lorawan_58aef822c5219cad = []byte{ + // 5197 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x7b, 0x4f, 0x6c, 0x23, 0xc9, + 0x75, 0x37, 0x29, 0x92, 0x22, 0xf5, 0x48, 0x8a, 0x3d, 0x25, 0xcd, 0x8c, 0x86, 0xde, 0xa5, 0xd6, + 0x9a, 0xfd, 0xf0, 0x8d, 0xc7, 0x1e, 0x8d, 0x44, 0x69, 0xb4, 0x5a, 0xaf, 0xff, 0xf1, 0x9f, 0x56, + 0xdc, 0x91, 0x48, 0xb9, 0x29, 0xcd, 0xec, 0x18, 0x36, 0xfa, 0x6b, 0xb1, 0x9b, 0x12, 0x57, 0x64, + 0x37, 0xb7, 0xd9, 0x1a, 0x49, 0xdf, 0x21, 0x58, 0x20, 0x97, 0x05, 0x72, 0x88, 0x11, 0x20, 0x40, + 0x8c, 0x1c, 0x6c, 0x24, 0x39, 0x18, 0x08, 0x82, 0x18, 0x08, 0x82, 0xec, 0xd1, 0x01, 0x72, 0x30, + 0x72, 0xda, 0x20, 0x17, 0xc3, 0x41, 0x64, 0x0f, 0xe7, 0xe2, 0x5c, 0x12, 0x1f, 0x7d, 0x0c, 0x5e, + 0x55, 0x35, 0xbb, 0xaa, 0x5b, 0x33, 0xd2, 0xec, 0xae, 0x4f, 0xea, 0xfa, 0xf5, 0xab, 0x57, 0xaf, + 0xde, 0xdf, 0x7a, 0xd5, 0x14, 0xcc, 0xf7, 0x6c, 0x47, 0x3f, 0xd1, 0xad, 0x7b, 0x43, 0x57, 0x6f, + 0x1f, 0xdd, 0xd7, 0x07, 0xdd, 0xfb, 0x1c, 0x59, 0x1c, 0x38, 0xb6, 0x6b, 0x93, 0x69, 0xd7, 0xb5, + 0x16, 0x3d, 0xe8, 0xe9, 0x4a, 0xfe, 0xde, 0x41, 0xd7, 0x3d, 0x3c, 0xde, 0x5f, 0x6c, 0xdb, 0xfd, + 0xfb, 0x07, 0xf6, 0x81, 0x7d, 0x9f, 0x92, 0xed, 0x1f, 0x77, 0xe8, 0x88, 0x0e, 0xe8, 0x13, 0x9b, + 0x9e, 0x5f, 0x13, 0xc8, 0xfb, 0x27, 0x5d, 0xf7, 0xc8, 0x3e, 0xb9, 0x7f, 0x60, 0xdf, 0xa3, 0x2f, + 0xef, 0x3d, 0xd5, 0x7b, 0x5d, 0x43, 0x77, 0x6d, 0x67, 0x78, 0x7f, 0xfc, 0xc8, 0xe7, 0xbd, 0x76, + 0x60, 0xdb, 0x07, 0x3d, 0xd3, 0xe7, 0x3e, 0x74, 0x9d, 0xe3, 0xb6, 0xcb, 0xdf, 0xce, 0x07, 0xdf, + 0xba, 0xdd, 0xbe, 0x39, 0x74, 0xf5, 0xfe, 0x80, 0x13, 0xdc, 0x0e, 0x6f, 0xab, 0x6b, 0x98, 0x96, + 0xdb, 0xed, 0x74, 0x4d, 0x67, 0xc8, 0x88, 0x16, 0xfe, 0x35, 0x06, 0xc9, 0x6d, 0x73, 0x38, 0xd4, + 0x0f, 0x4c, 0xb2, 0x02, 0x89, 0xbe, 0x76, 0x68, 0x38, 0x73, 0xd1, 0x37, 0xa2, 0x77, 0xd2, 0xc5, + 0xd9, 0x45, 0x79, 0xdb, 0x8b, 0xdb, 0x9b, 0x55, 0xb5, 0x9c, 0xfa, 0xc5, 0xf9, 0x7c, 0xe4, 0xd3, + 0xf3, 0xf9, 0xa8, 0x1a, 0xef, 0x6f, 0x1a, 0x0e, 0xb9, 0x05, 0xb1, 0x7e, 0xb7, 0x3d, 0x37, 0xf1, + 0x46, 0xf4, 0x4e, 0xa6, 0x9c, 0x1c, 0x9d, 0xcf, 0xc7, 0xb6, 0xeb, 0x15, 0x15, 0x31, 0xb2, 0x0d, + 0xe9, 0xbe, 0xde, 0xd6, 0x06, 0xfa, 0x59, 0xcf, 0xd6, 0x8d, 0xb9, 0x18, 0xe5, 0x9a, 0x0f, 0x71, + 0x2d, 0x55, 0x76, 0x18, 0x45, 0x79, 0x7a, 0x74, 0x3e, 0x0f, 0xfe, 0x78, 0x33, 0xa2, 0x42, 0x5f, + 0x6f, 0xf3, 0x11, 0x79, 0x04, 0xb3, 0x1f, 0xd8, 0x5d, 0x4b, 0x73, 0xcc, 0x0f, 0x8f, 0xcd, 0xa1, + 0x3b, 0xe6, 0x1b, 0xa7, 0x7c, 0x17, 0x82, 0x7c, 0xdf, 0xb3, 0xbb, 0x96, 0xca, 0x48, 0x7d, 0x7e, + 0xe4, 0x83, 0x10, 0x4a, 0x5a, 0x30, 0x43, 0xf9, 0xea, 0xed, 0xb6, 0x39, 0xf0, 0xd9, 0x26, 0x28, + 0xdb, 0x2f, 0x5f, 0xc4, 0xb6, 0x44, 0x29, 0x7d, 0xae, 0xd7, 0x3e, 0x08, 0x82, 0xe4, 0xfb, 0x70, + 0xc3, 0x31, 0x2f, 0x14, 0x77, 0x92, 0xf2, 0x7d, 0x33, 0xc8, 0x57, 0x35, 0x3f, 0xb8, 0x48, 0xe0, + 0x59, 0xe7, 0x02, 0xfc, 0xeb, 0xf1, 0x4f, 0x7e, 0x32, 0x1f, 0x29, 0x4f, 0x41, 0x92, 0x03, 0xef, + 0xc5, 0x53, 0x49, 0x25, 0xb5, 0xa0, 0x43, 0x1c, 0x6d, 0x44, 0xbe, 0x06, 0x93, 0x7d, 0xcd, 0x3d, + 0x1b, 0x98, 0xd4, 0x92, 0xd3, 0xc5, 0xeb, 0x21, 0x9d, 0xef, 0x9e, 0x0d, 0x4c, 0x35, 0xd1, 0xc7, + 0x3f, 0xe4, 0xab, 0x90, 0xe8, 0xeb, 0x1f, 0xd8, 0x0e, 0xb5, 0xe1, 0x45, 0xc4, 0xf8, 0x52, 0x65, + 0x34, 0x0b, 0xbf, 0x8a, 0x82, 0x60, 0x21, 0x74, 0x99, 0xce, 0xcb, 0x5c, 0x66, 0x23, 0xe0, 0x32, + 0x1d, 0x74, 0x99, 0x02, 0x4c, 0x76, 0xb4, 0x81, 0xed, 0xb8, 0x74, 0xc5, 0x6c, 0x39, 0x39, 0xfa, + 0xf5, 0x7c, 0x6c, 0xee, 0xa3, 0x09, 0x35, 0xd1, 0xd9, 0xb1, 0x1d, 0x97, 0xdc, 0x87, 0x74, 0xc7, + 0xe9, 0x4b, 0x7e, 0x93, 0x61, 0xbe, 0xb1, 0xa1, 0x6e, 0xf3, 0x95, 0x55, 0xe8, 0x38, 0x7d, 0x4f, + 0x8a, 0xef, 0x40, 0xce, 0x30, 0xdb, 0xb6, 0x61, 0x1a, 0x01, 0xa7, 0xb8, 0xb9, 0xc8, 0x82, 0x64, + 0xd1, 0x0b, 0x92, 0xc5, 0x16, 0x0d, 0x21, 0x75, 0x9a, 0xd3, 0x4b, 0x0a, 0x5d, 0xf8, 0xf7, 0x28, + 0xc4, 0x51, 0x62, 0xf2, 0x18, 0x52, 0x86, 0xf9, 0x54, 0xd3, 0x0d, 0xbe, 0xb3, 0x4c, 0xf9, 0x1b, + 0xb8, 0x87, 0x5f, 0x9d, 0xcf, 0xaf, 0x1e, 0xd8, 0x8b, 0xee, 0xa1, 0xe9, 0x1e, 0x76, 0xad, 0x83, + 0xe1, 0xa2, 0x65, 0xba, 0x27, 0xb6, 0x73, 0x74, 0x5f, 0x8e, 0xb4, 0xc1, 0xd1, 0xc1, 0x7d, 0xd4, + 0xfe, 0x70, 0xb1, 0x6a, 0x3e, 0x2d, 0x19, 0x86, 0xa3, 0x26, 0x0d, 0xf6, 0x40, 0xd6, 0x70, 0xeb, + 0x6d, 0xd7, 0xe9, 0xd1, 0xad, 0xa7, 0xc3, 0xca, 0xde, 0xa8, 0xb8, 0x4e, 0x4f, 0xd0, 0x58, 0xa2, + 0x83, 0x00, 0x79, 0x1d, 0xf5, 0xdc, 0xb6, 0x5c, 0xaa, 0x8c, 0x6c, 0x39, 0x35, 0xfa, 0xf5, 0x7c, + 0x7c, 0xee, 0xa3, 0x8f, 0xe2, 0x6a, 0xbc, 0x53, 0xb1, 0x5c, 0x72, 0x1d, 0xd9, 0xda, 0x03, 0x77, + 0x48, 0xf7, 0x9d, 0x51, 0x13, 0x9d, 0xe6, 0xc0, 0x1d, 0xf2, 0x5d, 0xfd, 0x28, 0x0a, 0x09, 0xca, + 0x16, 0x63, 0x55, 0xe7, 0x3b, 0x4a, 0xb1, 0x58, 0x2d, 0x55, 0x55, 0x15, 0x31, 0x72, 0x0f, 0xd2, + 0xba, 0xe1, 0x68, 0x7a, 0xfb, 0x08, 0x1d, 0x96, 0x4a, 0x97, 0x2a, 0x67, 0x47, 0xe7, 0xf3, 0x53, + 0xa5, 0xaa, 0x5a, 0x6a, 0x1f, 0xa9, 0xe6, 0x87, 0xea, 0x94, 0x6e, 0x38, 0xec, 0x91, 0x28, 0x10, + 0xd3, 0xdb, 0x47, 0x54, 0x9a, 0x94, 0x8a, 0x8f, 0xe4, 0x4b, 0x30, 0xd5, 0xd1, 0x06, 0xa6, 0x65, + 0x74, 0xad, 0x03, 0x2a, 0x45, 0x4a, 0x4d, 0x75, 0x76, 0xd8, 0x98, 0xdc, 0x84, 0x64, 0xbb, 0xa7, + 0x0f, 0x87, 0xda, 0x3e, 0x0d, 0xab, 0x94, 0x3a, 0x49, 0x87, 0xe5, 0x85, 0x7f, 0x9a, 0x00, 0x12, + 0x0e, 0x54, 0xf2, 0xff, 0x20, 0x45, 0x63, 0xc7, 0x3c, 0xee, 0x72, 0xfd, 0xd7, 0xb8, 0xfe, 0x8b, + 0xaf, 0xa4, 0xff, 0xda, 0x5e, 0x7d, 0x6d, 0x75, 0x74, 0x3e, 0x9f, 0xc4, 0x35, 0x6a, 0x7b, 0x75, + 0x35, 0x89, 0x6c, 0x6b, 0xc7, 0x5d, 0xf2, 0x03, 0x40, 0x9b, 0xd0, 0x05, 0x58, 0xea, 0xaa, 0x7e, + 0xae, 0x05, 0x26, 0xab, 0xe6, 0x53, 0xe4, 0x3f, 0x69, 0x98, 0x4f, 0x91, 0xfd, 0xf7, 0x60, 0x0a, + 0xd9, 0x5b, 0xb6, 0xd5, 0x36, 0xb9, 0x03, 0x7f, 0x93, 0x2f, 0xf0, 0xe0, 0x55, 0x3d, 0xa8, 0x81, + 0x4c, 0x54, 0x74, 0x48, 0xfa, 0xc4, 0xad, 0xfa, 0xe7, 0x31, 0x98, 0xbd, 0x28, 0x67, 0x90, 0x77, + 0x20, 0xcd, 0x33, 0x8f, 0x90, 0x01, 0xf2, 0x17, 0xa7, 0x1b, 0x9a, 0x06, 0xc0, 0x19, 0x3f, 0x93, + 0xef, 0xc1, 0xa4, 0x65, 0xba, 0x5a, 0xd7, 0xe0, 0x5a, 0xa9, 0x7c, 0x26, 0xad, 0x34, 0x4c, 0xb7, + 0x5e, 0x1d, 0x9d, 0xcf, 0x27, 0xe8, 0x83, 0x9a, 0xb0, 0x4c, 0xb7, 0x2e, 0x1b, 0x35, 0xf6, 0x87, + 0x36, 0x6a, 0xfc, 0x0f, 0x60, 0xd4, 0xd7, 0x81, 0xab, 0x8a, 0x46, 0x22, 0x3a, 0x72, 0x56, 0x9d, + 0x62, 0x48, 0xc5, 0x72, 0xb9, 0x5d, 0xfe, 0x38, 0x0e, 0xd7, 0x42, 0x35, 0x82, 0xbc, 0x06, 0x53, + 0xa6, 0xd5, 0x76, 0xce, 0x06, 0xae, 0x69, 0x30, 0x8f, 0x56, 0x7d, 0x80, 0xfc, 0x00, 0x80, 0xb2, + 0x65, 0xee, 0xc2, 0x34, 0xff, 0x2d, 0x2e, 0xfa, 0xda, 0x2b, 0x89, 0x8e, 0x2b, 0x33, 0x7f, 0x99, + 0xfa, 0xc0, 0x7b, 0x14, 0x8c, 0x1a, 0xfb, 0xc2, 0x8d, 0x2a, 0x66, 0xca, 0xf8, 0x17, 0x99, 0x29, + 0x6b, 0x90, 0x36, 0x7a, 0xda, 0xd0, 0x74, 0x5d, 0x9c, 0xcf, 0xab, 0x71, 0xc8, 0x8d, 0xab, 0x5b, + 0x2d, 0x4e, 0x21, 0xe4, 0x4c, 0x30, 0x7a, 0x1e, 0x4a, 0x8a, 0x90, 0x72, 0x4e, 0x35, 0xc3, 0xec, + 0xe9, 0x67, 0xb4, 0xf2, 0x4e, 0x17, 0x6f, 0x86, 0x42, 0xe1, 0xb4, 0x8a, 0xaf, 0xd5, 0xa4, 0xc3, + 0x1e, 0xc8, 0x3b, 0x90, 0x6c, 0x77, 0xb4, 0x5e, 0x77, 0xe8, 0xce, 0x25, 0xe9, 0xb2, 0x37, 0x82, + 0x53, 0x2a, 0x1b, 0x5b, 0xdd, 0xa1, 0x5b, 0x06, 0x74, 0x12, 0xf6, 0xac, 0x4e, 0xb6, 0x3b, 0xf8, + 0x97, 0x7b, 0xc1, 0xdf, 0x45, 0x01, 0x7c, 0xd9, 0xc8, 0x0a, 0x64, 0x9d, 0xd3, 0x65, 0xcd, 0x70, + 0x34, 0xbb, 0xd3, 0x19, 0x9a, 0x2e, 0x75, 0x81, 0x6c, 0x39, 0x37, 0x3a, 0x9f, 0x4f, 0xab, 0xa7, + 0xcb, 0x55, 0xb5, 0x49, 0x61, 0x35, 0xed, 0x9c, 0x2e, 0x57, 0x1d, 0x36, 0x20, 0xdf, 0x86, 0x49, + 0xe7, 0xb4, 0xa8, 0x19, 0x5e, 0x61, 0x7e, 0x3d, 0xb4, 0x79, 0xdd, 0xd5, 0x55, 0xdd, 0x35, 0xeb, + 0x96, 0x61, 0x9e, 0x96, 0xa7, 0xd0, 0x36, 0xea, 0x69, 0xb1, 0xaa, 0xaa, 0x09, 0xe7, 0xb4, 0x58, + 0x75, 0xc8, 0x6d, 0x48, 0xda, 0x03, 0x57, 0xb3, 0xcc, 0x03, 0x96, 0xa8, 0x99, 0xbc, 0xcd, 0x81, + 0xdb, 0x30, 0x0f, 0xd4, 0x49, 0x9b, 0xfe, 0xe5, 0xf2, 0xf6, 0x81, 0xef, 0x83, 0x2c, 0x42, 0xfc, + 0x65, 0x79, 0x83, 0x51, 0xd1, 0xbc, 0x41, 0xe9, 0x08, 0x81, 0x78, 0x87, 0x55, 0x8c, 0xd8, 0x9d, + 0xac, 0x4a, 0x9f, 0xc9, 0x2d, 0x48, 0xb5, 0x0f, 0xb5, 0xbe, 0x3e, 0x3c, 0x1a, 0xce, 0xc5, 0xde, + 0x88, 0xdd, 0x49, 0xa9, 0xc9, 0xf6, 0xe1, 0x36, 0x0e, 0xf9, 0x72, 0x8f, 0x21, 0xb3, 0x65, 0xab, + 0xba, 0xb7, 0x01, 0x0c, 0x8f, 0x7d, 0xdd, 0x32, 0x4e, 0xba, 0x86, 0x7b, 0xc8, 0x74, 0xa3, 0xfa, + 0x00, 0xf9, 0x0a, 0x28, 0xc3, 0x81, 0x63, 0xea, 0x58, 0x4a, 0xb4, 0x8e, 0xde, 0x76, 0xf9, 0x59, + 0x25, 0xab, 0xe6, 0xc6, 0xf8, 0x06, 0x85, 0x17, 0xee, 0x40, 0x7a, 0xa3, 0xf5, 0x70, 0xcc, 0xf7, + 0x16, 0xa4, 0xf6, 0xbb, 0xae, 0xe6, 0xe8, 0xae, 0xc9, 0xd9, 0x26, 0xf7, 0xbb, 0x2e, 0xbe, 0x5a, + 0xf8, 0x61, 0x14, 0x52, 0x63, 0xba, 0x6f, 0x40, 0x1c, 0xf7, 0xc8, 0x4f, 0x31, 0xaf, 0x05, 0x37, + 0x2d, 0xca, 0x5a, 0x4e, 0x8d, 0xce, 0xe7, 0xe3, 0x88, 0x6c, 0x46, 0x54, 0x3a, 0x8b, 0xac, 0x43, + 0xac, 0x33, 0x3c, 0xe2, 0x15, 0xfd, 0x4b, 0xa1, 0x8a, 0xee, 0xcb, 0xc3, 0x6a, 0xee, 0x46, 0xeb, + 0xe1, 0x66, 0x44, 0xc5, 0x29, 0xe5, 0x0c, 0x40, 0xdf, 0x36, 0x8e, 0x7b, 0xba, 0xdb, 0xb5, 0xad, + 0x85, 0xbf, 0x8c, 0x03, 0xec, 0x9e, 0x8e, 0x9d, 0xe6, 0x1d, 0x98, 0x32, 0x74, 0x57, 0xf7, 0xa5, + 0x4f, 0x17, 0xe7, 0x5e, 0xe4, 0x02, 0xe5, 0x38, 0x7a, 0xbf, 0x9a, 0x32, 0xbc, 0x1d, 0xd5, 0x20, + 0x37, 0x9e, 0xac, 0x75, 0xd1, 0x41, 0xae, 0xe4, 0x45, 0x6a, 0xd6, 0x10, 0x87, 0x64, 0x1e, 0xd2, + 0x6d, 0x9b, 0xea, 0x9d, 0x4a, 0x81, 0x6e, 0x34, 0xa5, 0x02, 0x83, 0x3c, 0xcb, 0x75, 0xe8, 0x09, + 0xd7, 0x6a, 0x9f, 0xd1, 0x04, 0x10, 0x57, 0x7d, 0x00, 0xf5, 0xef, 0x9e, 0x6a, 0x03, 0xfb, 0xc4, + 0x74, 0x68, 0x04, 0x27, 0xd4, 0xa4, 0x7b, 0xba, 0x83, 0x43, 0x72, 0x1f, 0x66, 0xba, 0xd6, 0x53, + 0xd3, 0x71, 0xb5, 0x81, 0xdd, 0xd3, 0x9d, 0xee, 0xff, 0xa7, 0x3a, 0xa0, 0x31, 0x9a, 0x52, 0x09, + 0x7b, 0xb5, 0x23, 0xbc, 0x21, 0xef, 0xc0, 0xf5, 0x03, 0xdd, 0x35, 0x4f, 0xf4, 0x33, 0xad, 0x7d, + 0xa8, 0x5b, 0x96, 0xd9, 0xe3, 0xfb, 0x4a, 0xca, 0x87, 0xc8, 0x19, 0x4e, 0x55, 0x61, 0x44, 0x6c, + 0x1f, 0x6f, 0xc3, 0xac, 0x61, 0x3e, 0xed, 0xb6, 0xcd, 0xc0, 0xdc, 0x94, 0x3c, 0x97, 0x30, 0x22, + 0x69, 0xea, 0xd7, 0x00, 0x4c, 0x4b, 0xdf, 0xef, 0x99, 0x5a, 0xdb, 0x69, 0xcf, 0x4d, 0xf9, 0x07, + 0xa3, 0x1a, 0x45, 0x2b, 0x6a, 0x05, 0x53, 0x39, 0x7d, 0x74, 0xda, 0xa8, 0x8f, 0x71, 0x1f, 0x36, + 0x07, 0xcc, 0x93, 0xc7, 0x00, 0x59, 0x85, 0x38, 0x0e, 0xe6, 0xd2, 0x3c, 0x9b, 0x05, 0x4f, 0xa7, + 0xbb, 0x1e, 0x65, 0x39, 0xfe, 0xc3, 0x5f, 0xe3, 0x79, 0x19, 0xa9, 0x79, 0xcc, 0xfc, 0x69, 0x14, + 0x6e, 0xbd, 0xcb, 0xb6, 0x56, 0xb2, 0x5c, 0xd3, 0xb2, 0xf4, 0xba, 0xdf, 0xcd, 0x61, 0xaf, 0xe5, + 0x69, 0xa7, 0x6b, 0x0c, 0xb9, 0xbb, 0x84, 0x7a, 0x22, 0x3e, 0x5f, 0x98, 0x28, 0xa6, 0xcd, 0x03, + 0xef, 0xed, 0x90, 0xdc, 0x86, 0xac, 0xce, 0x16, 0x11, 0x9c, 0x27, 0xab, 0x66, 0x38, 0x48, 0x35, + 0xb3, 0xe0, 0x40, 0x7a, 0x6f, 0xd0, 0xeb, 0x5a, 0x47, 0xbb, 0xf6, 0x91, 0x69, 0x91, 0x1a, 0xc4, + 0xfc, 0xa5, 0xbf, 0xf2, 0x82, 0xa5, 0xc3, 0xa2, 0x0b, 0x12, 0xe0, 0x7c, 0x59, 0x83, 0x13, 0x01, + 0x0d, 0x2e, 0xfc, 0x11, 0x64, 0xaa, 0xf6, 0x89, 0x85, 0xab, 0xee, 0xe8, 0xee, 0x21, 0xb9, 0x0d, + 0x99, 0x63, 0x2a, 0x83, 0xe6, 0xa2, 0x10, 0xac, 0xb6, 0x6e, 0x46, 0xd4, 0xf4, 0xb1, 0x20, 0x59, + 0x09, 0x12, 0x9d, 0xee, 0xa9, 0x69, 0xf0, 0x10, 0xbd, 0xba, 0x6c, 0x9b, 0x11, 0x95, 0xcd, 0x2c, + 0x4f, 0x42, 0x7c, 0xa0, 0xbb, 0x87, 0x0b, 0xff, 0x11, 0x87, 0xa9, 0xdd, 0x53, 0x7e, 0xe4, 0xc2, + 0xd6, 0x89, 0x1e, 0x64, 0x5f, 0xd4, 0x67, 0x55, 0xf0, 0xa5, 0xca, 0x68, 0x48, 0x05, 0xa6, 0x0d, + 0x2e, 0xba, 0x86, 0xbc, 0x86, 0x34, 0x67, 0x5e, 0x90, 0x6e, 0xc4, 0x0d, 0xaa, 0x59, 0x43, 0x18, + 0x0d, 0xc9, 0x2a, 0x4c, 0xd1, 0x4a, 0x42, 0x0b, 0x5a, 0xec, 0xe5, 0x05, 0x2d, 0x85, 0xd5, 0x84, + 0x56, 0xb4, 0x2d, 0x98, 0xa1, 0xb3, 0x02, 0x19, 0x21, 0x7e, 0x95, 0x8c, 0xa0, 0x20, 0x17, 0x29, + 0x29, 0xdc, 0x66, 0xd5, 0xcc, 0x8f, 0xfb, 0x04, 0x8d, 0xfb, 0x8c, 0x73, 0xba, 0xbc, 0x31, 0x0e, + 0x7d, 0xba, 0x64, 0x31, 0xb4, 0xe4, 0xe4, 0x15, 0x97, 0x2c, 0x5e, 0xb0, 0x64, 0x51, 0x58, 0x32, + 0xe9, 0x2d, 0x59, 0xf4, 0x97, 0xfc, 0x16, 0xa4, 0x06, 0x4e, 0xd7, 0x76, 0xba, 0xee, 0x19, 0x0d, + 0xec, 0xe9, 0x70, 0x00, 0xec, 0x9e, 0xb6, 0xda, 0x87, 0xa6, 0x71, 0xdc, 0x33, 0x77, 0x38, 0xa5, + 0x3a, 0x9e, 0x43, 0x6a, 0x90, 0xd5, 0xf7, 0x87, 0x76, 0xef, 0xd8, 0x35, 0x35, 0x1a, 0xa6, 0x53, + 0x57, 0x0c, 0xd3, 0x8c, 0x37, 0x0d, 0x5f, 0x90, 0x15, 0x48, 0xe9, 0xc6, 0x53, 0xdd, 0x6a, 0x9b, + 0xc6, 0x5c, 0xfb, 0xe5, 0x6d, 0xe8, 0x98, 0x90, 0xc7, 0xf8, 0x7f, 0x2d, 0xd1, 0xee, 0xba, 0x62, + 0xf7, 0xfb, 0xba, 0x65, 0x90, 0x6f, 0x43, 0xac, 0xdd, 0x35, 0xb8, 0x73, 0xbd, 0x79, 0xc1, 0xc5, + 0x09, 0x27, 0xf4, 0x3d, 0x96, 0x55, 0x98, 0x4a, 0xbd, 0xaa, 0xe2, 0x4c, 0xf2, 0x65, 0x48, 0x3b, + 0xfa, 0xc9, 0xb8, 0x29, 0x9e, 0xe0, 0xc1, 0x01, 0x8e, 0x7e, 0xe2, 0x9d, 0x4c, 0xcb, 0x30, 0xe5, + 0x98, 0x43, 0x3c, 0x1e, 0x5a, 0xde, 0x15, 0xcd, 0xed, 0x17, 0xaf, 0xb4, 0xa8, 0x22, 0x6d, 0xdd, + 0x32, 0x36, 0x23, 0x6a, 0xca, 0xe1, 0xcf, 0xa4, 0x86, 0x07, 0x63, 0xe4, 0xd1, 0xb6, 0xad, 0x0e, + 0x6f, 0xbd, 0xdf, 0xbc, 0x8c, 0x49, 0xc5, 0xb6, 0x3a, 0x9b, 0x11, 0x95, 0xad, 0x8e, 0x03, 0xd2, + 0x84, 0x69, 0x1a, 0x1c, 0xed, 0x43, 0xb3, 0x7d, 0xa4, 0xe9, 0x96, 0x77, 0xea, 0xfb, 0xbf, 0x2f, + 0x61, 0xb5, 0xd5, 0xb5, 0x8e, 0x2a, 0x48, 0x5f, 0xb2, 0x30, 0x5a, 0x33, 0x3d, 0x61, 0x4c, 0x9e, + 0x00, 0x1d, 0x6b, 0xd8, 0xd9, 0xe2, 0x19, 0x85, 0x5d, 0xbd, 0xfc, 0x9f, 0x4b, 0xd8, 0x61, 0x4f, + 0x6c, 0x7e, 0xc8, 0x2e, 0x1c, 0xfc, 0x31, 0xaa, 0x0d, 0x99, 0x95, 0x0c, 0x07, 0x1b, 0x60, 0x91, + 0x35, 0x4a, 0x9a, 0xbc, 0x2a, 0xeb, 0x92, 0x35, 0x94, 0x58, 0x33, 0xb9, 0x3d, 0xd6, 0x28, 0x75, + 0x13, 0xa6, 0x8d, 0x63, 0xf7, 0x4c, 0x6b, 0x9f, 0xb5, 0x7b, 0x26, 0x95, 0x3b, 0x75, 0xa9, 0x1a, + 0xaa, 0xc7, 0xee, 0x59, 0x05, 0xe9, 0x99, 0xa4, 0x19, 0x43, 0x18, 0x93, 0x27, 0x40, 0x9c, 0x53, + 0x6d, 0xa0, 0x3b, 0x7a, 0x1f, 0x0f, 0xd4, 0xc7, 0x03, 0xca, 0x94, 0x39, 0xf7, 0xdd, 0x97, 0x99, + 0xe9, 0x74, 0x07, 0xe7, 0xb4, 0x70, 0x0a, 0xe3, 0x9b, 0x73, 0x64, 0xe8, 0x02, 0xd6, 0xa8, 0x0c, + 0x78, 0x25, 0xd6, 0x4c, 0x03, 0x12, 0x6b, 0x4f, 0x0d, 0xe6, 0x53, 0x6d, 0xe8, 0xea, 0xee, 0xf1, + 0x90, 0xb2, 0x4d, 0x5f, 0xae, 0x06, 0xf3, 0x69, 0x8b, 0xd2, 0x73, 0x6f, 0x30, 0x84, 0x31, 0x51, + 0x21, 0x67, 0x99, 0x27, 0xe3, 0x03, 0x00, 0xea, 0x20, 0x43, 0x39, 0xde, 0x79, 0x09, 0xc7, 0x86, + 0x79, 0xc2, 0x4f, 0x03, 0x4c, 0x03, 0x59, 0x4b, 0x04, 0x82, 0x3c, 0x51, 0xca, 0xec, 0x2b, 0xf0, + 0x64, 0x62, 0x0a, 0x3c, 0x51, 0x4e, 0x1d, 0xa6, 0x8d, 0x9e, 0x24, 0xe6, 0xf4, 0xe5, 0x1b, 0xdf, + 0xf2, 0x85, 0x2a, 0x2b, 0xa3, 0xf3, 0xf9, 0x8c, 0x88, 0x50, 0x55, 0xf4, 0x04, 0xb1, 0xe5, 0x25, + 0x50, 0xea, 0xdc, 0xd5, 0x97, 0x40, 0x0f, 0x96, 0x97, 0xf0, 0xb4, 0xdd, 0x13, 0x76, 0xf1, 0x7d, + 0xcc, 0xff, 0x98, 0x46, 0xf1, 0xf0, 0xe8, 0x7b, 0x9d, 0x42, 0xd7, 0xf9, 0xea, 0x4b, 0x5d, 0x63, + 0x97, 0x4e, 0x12, 0xdc, 0x4e, 0x71, 0x02, 0x18, 0xfa, 0x9d, 0x1b, 0x76, 0xe9, 0x6b, 0x97, 0xfa, + 0xdd, 0x6e, 0xd8, 0xa5, 0xdd, 0x80, 0x4b, 0xd3, 0x84, 0x78, 0x64, 0x9e, 0xd1, 0x84, 0x48, 0xae, + 0x90, 0x10, 0x8f, 0xcc, 0xb3, 0x71, 0x42, 0x64, 0xcf, 0x2c, 0x21, 0x22, 0x0f, 0x9a, 0x10, 0x67, + 0xae, 0x90, 0x10, 0x8f, 0xcc, 0x33, 0x3f, 0x21, 0xf2, 0x01, 0x71, 0x60, 0x06, 0xf3, 0x4b, 0x70, + 0x9b, 0xb3, 0x97, 0xea, 0xb0, 0x54, 0x55, 0xa5, 0x4d, 0x95, 0x67, 0x47, 0xe7, 0xf3, 0x4a, 0x10, + 0x45, 0xcd, 0xea, 0x86, 0x23, 0x6f, 0x5f, 0x85, 0x1c, 0x3f, 0x29, 0x63, 0x09, 0xa4, 0xbe, 0x71, + 0xfd, 0x52, 0x8f, 0xae, 0xd2, 0x19, 0x58, 0xfd, 0xb8, 0x47, 0x1b, 0x22, 0x40, 0xf6, 0x40, 0xe9, + 0xd8, 0x4e, 0x1b, 0x93, 0x99, 0x77, 0x25, 0x3e, 0x77, 0xe3, 0xe2, 0xa3, 0x98, 0xc0, 0x74, 0x03, + 0xa7, 0x8c, 0xaf, 0xb8, 0x36, 0x23, 0xea, 0x74, 0x47, 0x42, 0x88, 0x39, 0xbe, 0x63, 0x0f, 0x6a, + 0xe8, 0x26, 0x65, 0xbe, 0xf8, 0x52, 0x8d, 0xe3, 0xc4, 0xa0, 0x3a, 0x66, 0x9c, 0x30, 0xfc, 0x82, + 0x65, 0x50, 0x31, 0x73, 0xaf, 0xbc, 0x0c, 0x53, 0x4f, 0x68, 0x19, 0x56, 0xac, 0xc8, 0x80, 0xc6, + 0x4a, 0xcf, 0xc6, 0x62, 0xdc, 0xb1, 0xe9, 0x4e, 0x6e, 0x5d, 0xea, 0xd2, 0x3b, 0x18, 0x17, 0x3d, + 0xdb, 0xad, 0x5b, 0x1d, 0x9b, 0xbb, 0xf4, 0x40, 0x86, 0xc8, 0x3e, 0x5c, 0xf7, 0x59, 0x8b, 0x89, + 0x25, 0x4f, 0xb9, 0xdf, 0xbb, 0x02, 0x77, 0x29, 0x99, 0x90, 0x41, 0x08, 0xbd, 0x78, 0x0d, 0x54, + 0xd2, 0x97, 0x5e, 0x75, 0x0d, 0xa6, 0xa3, 0xe0, 0x1a, 0xa8, 0xa2, 0xf7, 0xe1, 0xda, 0xbe, 0xa9, + 0xb7, 0x6d, 0xcb, 0xcb, 0x2b, 0xc8, 0xff, 0xb5, 0x4b, 0x35, 0x54, 0xa6, 0x73, 0x58, 0x06, 0xe1, + 0xc5, 0x66, 0x5f, 0x86, 0xd0, 0xeb, 0x39, 0x67, 0x3c, 0x62, 0x52, 0xdd, 0xbc, 0x7e, 0xa9, 0xd7, + 0x33, 0xbe, 0x78, 0xfe, 0xe4, 0xb5, 0x61, 0x5f, 0x04, 0x82, 0x3c, 0x51, 0xd6, 0xc2, 0x2b, 0xf0, + 0xe4, 0x91, 0xb4, 0x2f, 0x02, 0x42, 0x74, 0xf6, 0x6d, 0x83, 0x9e, 0xa9, 0xe7, 0xe6, 0xaf, 0x18, + 0x9d, 0xdb, 0xb6, 0x61, 0xb2, 0x3c, 0xc5, 0xa3, 0x93, 0x03, 0x18, 0x9d, 0x22, 0x4f, 0x9a, 0xb2, + 0xde, 0xb8, 0x34, 0x3a, 0x7d, 0xa6, 0x3c, 0x6f, 0x4d, 0x1b, 0x12, 0x92, 0xdf, 0x80, 0x94, 0x77, + 0x58, 0x24, 0x5f, 0x87, 0x6c, 0xbf, 0x6b, 0xd9, 0x8e, 0xf6, 0xd4, 0x74, 0x86, 0xd8, 0xe6, 0xbf, + 0xe8, 0xbb, 0x14, 0x12, 0xa9, 0x19, 0x4a, 0xfb, 0x88, 0x91, 0xe6, 0xdf, 0x85, 0xa9, 0xf1, 0x79, + 0xf1, 0x73, 0x31, 0x7a, 0x08, 0x19, 0xf1, 0xb4, 0x48, 0x6e, 0xc0, 0x64, 0x5f, 0x77, 0x0e, 0xba, + 0x16, 0xbf, 0x1a, 0xe2, 0x23, 0xec, 0x35, 0xc6, 0x17, 0x0d, 0xf6, 0xb1, 0xe5, 0x7a, 0xbd, 0xaf, + 0x77, 0xaf, 0x80, 0x58, 0xfe, 0x7f, 0xa2, 0x20, 0x1c, 0x0e, 0x2f, 0xba, 0x6e, 0x89, 0x7e, 0x86, + 0xeb, 0x96, 0x37, 0x61, 0xda, 0xbb, 0x2f, 0x91, 0xfb, 0x6e, 0x7e, 0x6b, 0xc2, 0xa8, 0xbe, 0x0c, + 0x19, 0x2f, 0xc0, 0xfa, 0xfa, 0xf0, 0x88, 0x5f, 0xb1, 0xa5, 0x39, 0xb6, 0xad, 0x0f, 0x8f, 0xc8, + 0x12, 0xcc, 0x8a, 0x24, 0x68, 0x54, 0xd7, 0xb1, 0x7b, 0xfc, 0xd2, 0x9a, 0x08, 0xa4, 0x15, 0xf6, + 0x86, 0xdc, 0x82, 0x94, 0xb5, 0xaf, 0xb9, 0x0e, 0xba, 0xe9, 0x24, 0xbb, 0x2a, 0xb3, 0xf6, 0x77, + 0x71, 0xf8, 0x5e, 0x3c, 0x15, 0x57, 0x12, 0xf9, 0x3f, 0xf3, 0x77, 0x8c, 0xda, 0xbb, 0x03, 0x8a, + 0xb4, 0x82, 0xde, 0x3e, 0x62, 0x1f, 0x96, 0xd4, 0x69, 0x81, 0x7b, 0xa9, 0x7d, 0x44, 0xee, 0xc1, + 0x4c, 0x40, 0x37, 0x94, 0x98, 0x7e, 0x62, 0x52, 0x15, 0x49, 0x01, 0x48, 0xfe, 0x55, 0x56, 0xda, + 0x7d, 0x1d, 0x68, 0xfe, 0x97, 0xa6, 0x9c, 0xa8, 0x87, 0x52, 0xfb, 0x28, 0xff, 0x04, 0x32, 0xe2, + 0xd1, 0x97, 0xd4, 0x61, 0xba, 0xaf, 0x9f, 0x6a, 0xfe, 0xf9, 0x99, 0x9b, 0x21, 0x54, 0xc1, 0x4b, + 0x07, 0x07, 0x8e, 0x89, 0x16, 0x35, 0xfc, 0xf9, 0x99, 0xbe, 0x7e, 0x3a, 0x1e, 0xe5, 0xff, 0x31, + 0x0a, 0xb9, 0xc0, 0x09, 0xf8, 0x45, 0x4d, 0x6d, 0xf4, 0xb3, 0x35, 0xb5, 0xf7, 0x61, 0x56, 0xee, + 0xca, 0xf9, 0xe5, 0x30, 0xb3, 0xf9, 0x35, 0xa1, 0xef, 0xe6, 0x37, 0xc2, 0xa1, 0x2e, 0x38, 0x16, + 0xee, 0x82, 0xf3, 0x7f, 0x1b, 0x90, 0x1b, 0x8d, 0xb5, 0x0a, 0x37, 0x2f, 0x90, 0x5b, 0xb0, 0xd9, + 0x4c, 0x50, 0x38, 0xb4, 0xc4, 0x1a, 0xcc, 0x5d, 0x24, 0x9f, 0x60, 0xbd, 0xd9, 0x90, 0x8c, 0x38, + 0xef, 0x2e, 0x5c, 0x93, 0xc4, 0x14, 0x0d, 0x28, 0x8a, 0x8a, 0x06, 0xfc, 0x0e, 0x64, 0xc4, 0x43, + 0x3b, 0x99, 0x83, 0xe4, 0xbe, 0xee, 0xba, 0xa6, 0x73, 0x36, 0xbe, 0xb0, 0x65, 0x43, 0x21, 0x5c, + 0x27, 0xe8, 0x4d, 0x22, 0x1f, 0xe5, 0xff, 0x3b, 0x0a, 0x59, 0xe9, 0x94, 0x8e, 0x6a, 0x92, 0x6f, + 0xf9, 0x18, 0x27, 0x2f, 0x68, 0x98, 0xf2, 0xa5, 0x8b, 0xcb, 0x89, 0xe0, 0xc5, 0xe5, 0x16, 0xcc, + 0xf4, 0xbb, 0x56, 0xc8, 0xd0, 0xb1, 0x2b, 0x19, 0xba, 0xdf, 0xb5, 0x64, 0x43, 0x23, 0x37, 0xf4, + 0xca, 0xcf, 0x74, 0xfd, 0x82, 0x4e, 0x29, 0x22, 0xf9, 0xf7, 0xc5, 0xfd, 0xa2, 0xce, 0x6e, 0x43, + 0x56, 0xd6, 0x35, 0xb3, 0x69, 0xa6, 0x23, 0x28, 0x9a, 0x2c, 0x40, 0xd6, 0x5f, 0xdf, 0xb7, 0x60, + 0xda, 0x8b, 0x3f, 0x34, 0xc6, 0x77, 0x41, 0x6a, 0x1b, 0xbe, 0x00, 0x45, 0xe6, 0x35, 0x90, 0xda, + 0x04, 0xf4, 0x0d, 0x89, 0xa5, 0x20, 0x6f, 0x4e, 0x64, 0x8b, 0x22, 0x87, 0xf6, 0x35, 0x11, 0xde, + 0x57, 0xbe, 0x04, 0x4a, 0xb0, 0x63, 0x20, 0xf7, 0x20, 0xc1, 0x2e, 0xc8, 0xa2, 0x2f, 0xbf, 0x20, + 0x63, 0x54, 0xf9, 0x7f, 0x8e, 0x42, 0x2e, 0xd0, 0x18, 0x10, 0x95, 0x25, 0x12, 0xb3, 0xeb, 0x0c, + 0xa4, 0x20, 0x0f, 0x7f, 0x81, 0xa2, 0x55, 0xaf, 0x56, 0x57, 0x77, 0x58, 0x53, 0xb4, 0xad, 0x9f, + 0xe2, 0x80, 0x19, 0x0f, 0x33, 0x4a, 0xad, 0xeb, 0x0c, 0x98, 0xa6, 0xee, 0xc2, 0x35, 0x7e, 0x57, + 0x69, 0x9c, 0x98, 0xbd, 0x1e, 0xbb, 0x63, 0x62, 0x7b, 0xca, 0xb1, 0x17, 0x55, 0xc4, 0xe9, 0x25, + 0xd2, 0x22, 0xcc, 0x8c, 0x2f, 0x0b, 0x05, 0x6a, 0x16, 0x45, 0xd7, 0xbc, 0x57, 0x63, 0x7a, 0x56, + 0x6d, 0x79, 0xf7, 0xf1, 0xb9, 0xab, 0xad, 0xd7, 0x7f, 0x7c, 0x1e, 0x46, 0xbf, 0x8f, 0x42, 0xa8, + 0xe1, 0x20, 0x1f, 0xc2, 0x0d, 0xef, 0x57, 0x06, 0xbd, 0x6e, 0xbf, 0xeb, 0x6a, 0xe6, 0xe9, 0xc0, + 0xb6, 0x4c, 0xcb, 0x7d, 0x61, 0x9a, 0xa6, 0x3f, 0x3e, 0xd8, 0x42, 0xda, 0x1a, 0x27, 0x2d, 0xdf, + 0x1c, 0x9d, 0xcf, 0xcf, 0x5c, 0xf0, 0x42, 0x9d, 0x61, 0xbf, 0x4f, 0x90, 0x40, 0x71, 0x49, 0x6a, + 0x6d, 0x7f, 0xc9, 0x89, 0x97, 0x2d, 0x49, 0x1d, 0xe4, 0xa2, 0x25, 0xa5, 0x17, 0xde, 0x92, 0x12, + 0x98, 0xaf, 0x43, 0x56, 0x6a, 0x88, 0xc8, 0x3a, 0xbf, 0xf6, 0x4f, 0x5e, 0x7a, 0x9f, 0x48, 0xef, + 0xc2, 0xfd, 0xab, 0xff, 0xfc, 0x6f, 0xa3, 0x30, 0x2d, 0xf7, 0x41, 0x64, 0x3e, 0xfc, 0x7d, 0x3f, + 0x2b, 0x7d, 0xc3, 0xff, 0xe2, 0x3e, 0xfd, 0x60, 0x04, 0x38, 0xa6, 0xeb, 0x74, 0xcd, 0x21, 0xfb, + 0xe1, 0x89, 0x0a, 0x7d, 0xfd, 0x54, 0x65, 0x08, 0xd9, 0x86, 0xdc, 0xc0, 0x74, 0xba, 0xb6, 0xe1, + 0xab, 0x34, 0x7e, 0xf1, 0x4d, 0x25, 0xef, 0x82, 0x28, 0xf1, 0x58, 0x75, 0xd3, 0x03, 0x69, 0x9c, + 0xff, 0x24, 0x0a, 0x33, 0x17, 0x74, 0x65, 0xe4, 0xbb, 0x40, 0x50, 0x0e, 0x7a, 0x14, 0xbb, 0xd4, + 0x5f, 0x18, 0x03, 0x7a, 0x44, 0x1b, 0x2f, 0x84, 0x19, 0x54, 0x42, 0x48, 0x03, 0xae, 0x21, 0x4b, + 0xda, 0xe0, 0x06, 0xdc, 0x61, 0xe1, 0x05, 0x3f, 0x94, 0xe8, 0xf6, 0xcd, 0x31, 0xc3, 0x5c, 0x5f, + 0x3f, 0x15, 0x81, 0xfc, 0x66, 0x58, 0x72, 0x34, 0xfb, 0x32, 0x5c, 0x0f, 0x2d, 0x23, 0xe4, 0x3b, + 0x12, 0x60, 0x83, 0xd9, 0xac, 0x0e, 0xb9, 0x40, 0x3f, 0x47, 0xd6, 0x60, 0x92, 0x69, 0x8a, 0xef, + 0xb9, 0x10, 0x94, 0xd0, 0x9b, 0xc0, 0xf4, 0xab, 0x72, 0xea, 0xfc, 0x19, 0x90, 0x70, 0xf3, 0x26, + 0x67, 0xeb, 0x68, 0xb0, 0xec, 0x7d, 0x31, 0xae, 0x93, 0x3f, 0x0c, 0x2d, 0x7d, 0xe5, 0x32, 0xf5, + 0x6a, 0x87, 0xc5, 0xfc, 0x16, 0xe4, 0x02, 0xdd, 0x1d, 0x99, 0x15, 0x93, 0x7f, 0x96, 0xe7, 0xf8, + 0x70, 0x29, 0x9b, 0x08, 0x97, 0xb2, 0xfc, 0x3d, 0xc8, 0x4a, 0x3d, 0xdd, 0xcb, 0xb5, 0x95, 0x5f, + 0x15, 0xc9, 0xaf, 0xba, 0xc3, 0xfc, 0x37, 0xbc, 0xec, 0xe0, 0xf5, 0x5f, 0xaf, 0xf2, 0x11, 0x29, + 0xff, 0x4d, 0x98, 0x96, 0x3b, 0xaf, 0x57, 0x9a, 0x5e, 0x9e, 0x82, 0x24, 0xff, 0x18, 0x70, 0xf7, + 0xc7, 0x51, 0x48, 0xd0, 0xdf, 0x01, 0x12, 0x05, 0x32, 0xef, 0x35, 0xeb, 0x0d, 0x4d, 0xad, 0x7d, + 0x77, 0xaf, 0xd6, 0xda, 0x55, 0x22, 0x24, 0x07, 0x69, 0x8a, 0x94, 0x2a, 0x95, 0xda, 0xce, 0xae, + 0x12, 0x25, 0x04, 0xa6, 0xf7, 0x1a, 0x95, 0x66, 0x63, 0xa3, 0xae, 0x6e, 0xd7, 0xaa, 0xda, 0xde, + 0x8e, 0x32, 0x41, 0x66, 0x41, 0x11, 0xb1, 0x6a, 0xf3, 0x71, 0x43, 0x89, 0x21, 0x33, 0x89, 0x2e, + 0x8e, 0x73, 0x03, 0x54, 0x09, 0xc4, 0xd4, 0x9a, 0xb4, 0xe8, 0x24, 0x2e, 0xba, 0xa3, 0x36, 0x77, + 0xd4, 0x7a, 0x6d, 0xb7, 0xa4, 0x3e, 0x51, 0x92, 0x77, 0x6f, 0x42, 0x82, 0xfe, 0xf6, 0x90, 0x4c, + 0x03, 0x6c, 0x35, 0xd5, 0xd2, 0xe3, 0x52, 0x43, 0x53, 0x97, 0x95, 0xc8, 0xdd, 0x36, 0xfd, 0x4a, + 0xc2, 0x2b, 0x0d, 0xce, 0xdb, 0x2e, 0x55, 0xb4, 0xbd, 0xc6, 0xc3, 0x06, 0x32, 0x8f, 0x90, 0x0c, + 0xa4, 0x10, 0x78, 0xb4, 0xac, 0x2d, 0x29, 0x51, 0x9c, 0xec, 0x8d, 0xb4, 0x65, 0x65, 0x42, 0x1a, + 0x17, 0x95, 0x98, 0x40, 0xbd, 0xac, 0xc4, 0xf3, 0xa9, 0x8f, 0xff, 0xba, 0x10, 0xf9, 0xd9, 0xdf, + 0x14, 0x22, 0x77, 0x7f, 0x14, 0x05, 0xd8, 0xd9, 0x7c, 0x22, 0xac, 0xb2, 0xb3, 0xf9, 0x44, 0x5e, + 0x05, 0x01, 0x7f, 0x15, 0x6f, 0x44, 0x57, 0x99, 0x05, 0x65, 0x3c, 0x2e, 0x6a, 0x6a, 0xed, 0x91, + 0x56, 0x52, 0x62, 0x17, 0xa0, 0x65, 0xa6, 0x20, 0x8e, 0x2e, 0x73, 0xca, 0x44, 0x08, 0x2b, 0x2b, + 0x93, 0x82, 0x6c, 0x7f, 0x3f, 0x01, 0x59, 0xf9, 0x88, 0x99, 0x83, 0x74, 0xb5, 0xb4, 0x5b, 0xd2, + 0xd4, 0xd2, 0x6e, 0x4d, 0x5b, 0x62, 0x26, 0xf4, 0x81, 0x65, 0x25, 0x2a, 0x03, 0x45, 0x65, 0x42, + 0x06, 0x56, 0x94, 0x98, 0x0c, 0xac, 0x2a, 0x71, 0x19, 0x78, 0xa0, 0x24, 0x64, 0x60, 0x8d, 0xd9, + 0xcc, 0x07, 0xde, 0x52, 0x92, 0x32, 0xb0, 0xae, 0xa4, 0x64, 0xe0, 0x6d, 0x65, 0x0a, 0x1d, 0x44, + 0x10, 0x6c, 0x49, 0x81, 0x00, 0xb2, 0xac, 0xa4, 0x03, 0x48, 0x51, 0xc9, 0x04, 0x90, 0x15, 0x25, + 0x1b, 0x40, 0x56, 0x95, 0xe9, 0x00, 0xf2, 0x40, 0xc9, 0x09, 0x1a, 0x5b, 0x02, 0xf0, 0x7f, 0xf2, + 0x46, 0xd2, 0x90, 0xac, 0x34, 0x1b, 0xbb, 0xb5, 0xf7, 0xd1, 0xd9, 0xd3, 0x90, 0x6c, 0xd5, 0x5a, + 0xad, 0x7a, 0xb3, 0xa1, 0x44, 0x49, 0x0a, 0xe2, 0x0f, 0x6b, 0x4f, 0x5a, 0xca, 0x04, 0xce, 0xf0, + 0x7f, 0xec, 0x82, 0xdb, 0xd8, 0xa0, 0xae, 0xda, 0xa8, 0xd4, 0x6b, 0x2d, 0x25, 0x42, 0xae, 0x41, + 0xb6, 0xb2, 0x59, 0x6a, 0x34, 0x6a, 0x5b, 0xda, 0x76, 0xa9, 0xf5, 0xb0, 0xa5, 0x44, 0xef, 0xae, + 0x42, 0x82, 0x06, 0x1b, 0x65, 0xbf, 0x55, 0x6a, 0xb5, 0xb4, 0x12, 0x63, 0xcf, 0x06, 0x65, 0x25, + 0xea, 0x0f, 0x2a, 0xca, 0x44, 0x3e, 0x8e, 0xd2, 0xdd, 0x1d, 0x00, 0x09, 0x7f, 0x95, 0x24, 0x00, + 0x93, 0x5b, 0xcd, 0xc7, 0x2c, 0x1a, 0x93, 0x10, 0xdb, 0x6a, 0x3e, 0x56, 0xa2, 0xb8, 0xc1, 0x72, + 0x6d, 0xab, 0xf9, 0x58, 0x6b, 0x34, 0xd5, 0xed, 0xd2, 0x96, 0x32, 0x81, 0x64, 0xfc, 0x99, 0x46, + 0x5e, 0xa9, 0xdc, 0x7c, 0x54, 0xf3, 0xde, 0xc6, 0x71, 0x33, 0x9b, 0xf5, 0x77, 0x37, 0x95, 0x04, + 0xae, 0x8b, 0x4f, 0x34, 0xd0, 0xee, 0xfe, 0x67, 0x0c, 0x66, 0x2f, 0xfa, 0x78, 0x48, 0xb2, 0x30, + 0x55, 0xa9, 0x57, 0x35, 0x75, 0x63, 0x8f, 0xba, 0x90, 0x37, 0xac, 0xb5, 0x6a, 0x3c, 0x07, 0xe0, + 0x70, 0xab, 0xde, 0x78, 0xa8, 0x55, 0x36, 0x6b, 0x95, 0x87, 0xca, 0x04, 0x8d, 0x76, 0x0f, 0x2b, + 0x55, 0x55, 0x25, 0xe6, 0x51, 0x55, 0xf7, 0x76, 0x9f, 0x68, 0x95, 0x27, 0x95, 0xad, 0x9a, 0x12, + 0x27, 0x37, 0x80, 0x50, 0x46, 0xef, 0x6b, 0x3b, 0x25, 0xb5, 0xb4, 0xad, 0xb5, 0x6a, 0xbb, 0x7b, + 0x3b, 0xcc, 0xc9, 0x29, 0x6d, 0xed, 0x91, 0xd6, 0xda, 0x2d, 0xed, 0xee, 0xb5, 0x94, 0x49, 0x32, + 0x03, 0x39, 0xc4, 0x1a, 0xb5, 0xc7, 0x1a, 0xd7, 0xaf, 0x92, 0x24, 0x37, 0x61, 0x86, 0x33, 0xd8, + 0xad, 0x6f, 0xd7, 0x1b, 0xef, 0x72, 0x0e, 0x29, 0x8f, 0xf3, 0xae, 0xcc, 0x79, 0x6a, 0xcc, 0x79, + 0x6b, 0xcc, 0x04, 0xfc, 0xed, 0x3c, 0xac, 0x3d, 0x51, 0xd2, 0x1e, 0xcf, 0x52, 0x55, 0x95, 0xe6, + 0x66, 0x3c, 0x09, 0xaa, 0xb5, 0x47, 0xf5, 0x4a, 0x0d, 0x17, 0xac, 0x29, 0x59, 0x8c, 0x5c, 0x04, + 0x37, 0x9a, 0x6a, 0xa5, 0xa6, 0xb1, 0xd4, 0xa5, 0x4c, 0x93, 0x3c, 0xdc, 0x60, 0x2c, 0x69, 0x2a, + 0x13, 0xd9, 0xe4, 0x3c, 0xd1, 0x76, 0xa8, 0xb8, 0x5b, 0xcd, 0x5d, 0xad, 0xde, 0xd8, 0x68, 0x2a, + 0x0a, 0xb9, 0x05, 0xd7, 0x65, 0xdc, 0x93, 0xf0, 0x1a, 0xb9, 0x0e, 0xd7, 0xf0, 0x55, 0xb9, 0x56, + 0xaa, 0x34, 0x1b, 0x7c, 0xab, 0x0a, 0xf1, 0x04, 0xe2, 0x30, 0xba, 0xa1, 0x32, 0x13, 0x90, 0x72, + 0xbb, 0x59, 0xad, 0x29, 0x6f, 0x70, 0x8f, 0xfa, 0xe5, 0x04, 0xcc, 0x5c, 0x70, 0xbf, 0x41, 0xe3, + 0x63, 0x6c, 0x16, 0x6d, 0x59, 0x89, 0x04, 0x90, 0x22, 0x73, 0x31, 0x01, 0x59, 0x65, 0x26, 0x16, + 0x90, 0x75, 0x25, 0x86, 0xae, 0x2f, 0xf2, 0x59, 0x53, 0xe2, 0x01, 0x68, 0xa5, 0xa8, 0x24, 0x02, + 0xd0, 0xda, 0xaa, 0x32, 0x89, 0x56, 0x11, 0x27, 0x16, 0xd7, 0x95, 0x64, 0x00, 0x2b, 0x3e, 0x58, + 0x53, 0x52, 0x01, 0xec, 0xc1, 0x72, 0x51, 0x99, 0xc2, 0xfd, 0x8a, 0x73, 0x97, 0x8a, 0xab, 0x0a, + 0x04, 0xc0, 0xe2, 0xd2, 0xea, 0xba, 0x92, 0x0e, 0x80, 0xab, 0x4b, 0x6f, 0xaf, 0x31, 0xa3, 0x8a, + 0xbb, 0x58, 0x7e, 0xbb, 0xc8, 0x8c, 0x2a, 0x6d, 0x64, 0x65, 0x1d, 0xd3, 0x88, 0x8c, 0xae, 0x14, + 0xdf, 0x5a, 0x5b, 0x57, 0x72, 0x5c, 0xb5, 0xff, 0x10, 0x85, 0x69, 0xf9, 0xbc, 0x85, 0xfb, 0xa4, + 0xb6, 0xac, 0x3d, 0xaa, 0xa9, 0x4f, 0xb4, 0x65, 0x9e, 0x1b, 0x04, 0xa8, 0xd8, 0x52, 0xa2, 0x01, + 0x68, 0xb5, 0xa5, 0x4c, 0x04, 0xa0, 0xf5, 0x16, 0x0b, 0x1e, 0x91, 0xd7, 0x5a, 0x8b, 0x57, 0x07, + 0x1f, 0x5b, 0x29, 0xb6, 0x78, 0x75, 0xf0, 0xb1, 0xb5, 0x55, 0x1e, 0x38, 0xe2, 0xdc, 0xe2, 0x7a, + 0x4b, 0x49, 0x72, 0xa9, 0xff, 0x24, 0xe6, 0x1d, 0x50, 0xe5, 0x73, 0xf0, 0x0c, 0xe4, 0xb8, 0xeb, + 0x56, 0x9a, 0x7b, 0x8d, 0x5d, 0x34, 0x65, 0x24, 0x04, 0xae, 0xa0, 0x5b, 0x04, 0xc1, 0xb5, 0x55, + 0x56, 0xe3, 0xe4, 0xe9, 0xc5, 0x75, 0x56, 0xe3, 0x24, 0x14, 0x4d, 0x1a, 0x0f, 0xa1, 0x68, 0xd4, + 0x04, 0x3a, 0xbc, 0xcc, 0x01, 0xcd, 0x3a, 0x19, 0x82, 0xa9, 0x61, 0x93, 0x21, 0x98, 0x9a, 0x36, + 0x15, 0x82, 0xa9, 0x71, 0xa7, 0x30, 0xfe, 0x02, 0x9b, 0x43, 0xf3, 0x42, 0x08, 0x67, 0x06, 0x4e, + 0x87, 0xf0, 0xb5, 0x07, 0x0f, 0x56, 0xd0, 0x73, 0x6e, 0xc2, 0x8c, 0xcc, 0x67, 0x65, 0x79, 0xe9, + 0x2d, 0xf4, 0x9e, 0xe0, 0x8b, 0xe2, 0x5a, 0x71, 0x79, 0x15, 0x1d, 0x28, 0xf8, 0xe2, 0x41, 0x71, + 0xb5, 0xb8, 0xee, 0xfb, 0xd0, 0xa7, 0x13, 0x40, 0xc2, 0x5d, 0x05, 0xba, 0x03, 0x9f, 0x85, 0x29, + 0x87, 0x26, 0xe0, 0x00, 0xb4, 0xcc, 0xfc, 0x48, 0x84, 0x8a, 0xcc, 0x8f, 0x44, 0x68, 0x85, 0x45, + 0xa8, 0x08, 0xad, 0xb2, 0x08, 0x15, 0xa1, 0x07, 0x2c, 0x42, 0x45, 0x08, 0xeb, 0x79, 0x00, 0xc2, + 0x8a, 0x1e, 0x80, 0xb0, 0xa6, 0x07, 0xa0, 0xb7, 0x59, 0xc2, 0x95, 0x44, 0xc5, 0xba, 0x1e, 0xc4, + 0xb0, 0xb2, 0x07, 0x31, 0xac, 0xed, 0x41, 0x0c, 0xab, 0x7b, 0x10, 0x43, 0xbd, 0x06, 0xb1, 0x07, + 0x63, 0x95, 0xfe, 0x4b, 0xd4, 0xfb, 0x31, 0xbc, 0xdc, 0x64, 0x0a, 0x7e, 0xbb, 0x53, 0x53, 0xeb, + 0xcd, 0x2a, 0x55, 0x6b, 0x08, 0x5c, 0x96, 0x3c, 0x9c, 0x83, 0xa8, 0xda, 0x10, 0x88, 0xca, 0x0d, + 0x81, 0xa8, 0xde, 0x10, 0x88, 0x0a, 0x0e, 0x81, 0x6b, 0x2c, 0x4e, 0x65, 0xf0, 0xad, 0x71, 0x9c, + 0xfe, 0xdb, 0x04, 0x80, 0x7f, 0x9f, 0x44, 0x33, 0x28, 0x4b, 0xef, 0x38, 0xd4, 0xd6, 0x95, 0x08, + 0xcd, 0x8c, 0x02, 0xb4, 0xbc, 0xc4, 0xea, 0xb2, 0x84, 0xa1, 0xe0, 0x41, 0x6c, 0x85, 0x25, 0x17, + 0x09, 0x5b, 0x65, 0xc9, 0x45, 0xc2, 0xd6, 0x58, 0x72, 0x91, 0xb0, 0x75, 0x9e, 0xb9, 0x05, 0xac, + 0xb8, 0xc4, 0x33, 0xb7, 0x88, 0x2d, 0xf3, 0xcc, 0x2d, 0x62, 0xab, 0xcc, 0x35, 0x24, 0x6c, 0x8d, + 0xb9, 0x86, 0x84, 0xbd, 0xc5, 0x5c, 0x43, 0xc2, 0xde, 0x66, 0xae, 0x21, 0x62, 0x2b, 0x4b, 0xcc, + 0x35, 0x24, 0x6c, 0x85, 0xb9, 0x86, 0x84, 0xad, 0x8d, 0x5d, 0xe3, 0xe3, 0x18, 0x5c, 0x74, 0x59, + 0x84, 0x66, 0xc0, 0xd2, 0x5f, 0xaa, 0x3c, 0xd4, 0xb6, 0xea, 0xdb, 0xf5, 0x5d, 0x5a, 0x0f, 0x43, + 0x20, 0xcf, 0x7d, 0x32, 0xb8, 0xca, 0x3c, 0x43, 0x06, 0x79, 0xea, 0x0b, 0xf0, 0xe4, 0xa9, 0x4f, + 0x46, 0x69, 0x79, 0x0c, 0xa1, 0x6b, 0x3c, 0xf3, 0x05, 0x38, 0x14, 0x79, 0xe6, 0x0b, 0xc8, 0xf5, + 0x80, 0x67, 0x3e, 0x19, 0x66, 0xa5, 0xf2, 0x06, 0x90, 0x00, 0x13, 0x56, 0x2d, 0x43, 0x38, 0x2f, + 0x98, 0x21, 0x9c, 0xd7, 0xcc, 0x10, 0xce, 0xcb, 0xe6, 0x4d, 0xaa, 0x51, 0x69, 0x9b, 0xac, 0x72, + 0x86, 0x5e, 0xc8, 0xc5, 0xd3, 0x37, 0x85, 0x74, 0x5f, 0x26, 0xea, 0xb2, 0x5a, 0xdb, 0x2a, 0x3d, + 0x09, 0x9a, 0x82, 0x81, 0x01, 0x53, 0x30, 0x30, 0x60, 0x0a, 0x06, 0x06, 0x4c, 0xc1, 0x79, 0x06, + 0x4c, 0xc1, 0xd0, 0xa0, 0x29, 0x18, 0x1a, 0x34, 0x05, 0xe7, 0x10, 0x34, 0x05, 0x97, 0x2b, 0x68, + 0x0a, 0x06, 0x87, 0x4c, 0xc1, 0x99, 0x84, 0x4c, 0xc1, 0xb9, 0x84, 0x4c, 0xc1, 0x37, 0x18, 0x32, + 0x05, 0xdf, 0x63, 0xc8, 0x14, 0xde, 0x36, 0x43, 0xa6, 0xf0, 0x76, 0x2a, 0x9a, 0xe2, 0x47, 0x13, + 0x90, 0xe4, 0xb7, 0xe0, 0xd8, 0xba, 0xaa, 0xef, 0x73, 0x2a, 0x4c, 0x8f, 0xe2, 0x78, 0x99, 0xb5, + 0xb6, 0xe3, 0x71, 0x91, 0x35, 0xd0, 0xe3, 0x31, 0xe6, 0x15, 0x71, 0x8c, 0x39, 0x45, 0x1c, 0x63, + 0x16, 0x14, 0xc7, 0x98, 0x00, 0xc5, 0x31, 0x16, 0x18, 0x71, 0x8c, 0xd5, 0x45, 0x1c, 0x63, 0x69, + 0xc9, 0x41, 0xda, 0x97, 0x07, 0xeb, 0x8a, 0x04, 0x60, 0x51, 0x91, 0x00, 0xac, 0x28, 0x12, 0x80, + 0xe5, 0x44, 0x02, 0x50, 0x3f, 0x12, 0x20, 0xb7, 0x8a, 0x3f, 0x9e, 0x80, 0x04, 0xbd, 0xd1, 0xa6, + 0x37, 0x0b, 0xf5, 0x46, 0x53, 0x1d, 0x77, 0x44, 0x69, 0x48, 0x32, 0x80, 0x37, 0xd4, 0xfe, 0x5b, + 0xde, 0x50, 0xfb, 0x00, 0x6f, 0xa8, 0x7d, 0x80, 0x37, 0xd4, 0x3e, 0xc0, 0x1b, 0x6a, 0x1f, 0xe0, + 0x0d, 0xb5, 0x0f, 0xf0, 0x86, 0xda, 0x07, 0x78, 0x43, 0xed, 0x03, 0xbc, 0xa1, 0xf6, 0x01, 0xaf, + 0xa1, 0x16, 0x10, 0xde, 0x50, 0x0b, 0x08, 0x6f, 0xa8, 0x05, 0x84, 0x37, 0xd4, 0x02, 0xc2, 0x1b, + 0x6a, 0x01, 0x19, 0x97, 0xdb, 0xf2, 0x5f, 0x45, 0x7f, 0xf1, 0xac, 0x10, 0xfd, 0xf4, 0x59, 0x21, + 0xfa, 0xcb, 0x67, 0x85, 0xc8, 0x6f, 0x9e, 0x15, 0x22, 0xbf, 0x7d, 0x56, 0x88, 0xfc, 0xee, 0x59, + 0x21, 0xf2, 0xfb, 0x67, 0x85, 0xe8, 0x47, 0xa3, 0x42, 0xf4, 0xe3, 0x51, 0x21, 0xf2, 0xd3, 0x51, + 0x21, 0xfa, 0xb3, 0x51, 0x21, 0xf2, 0xc9, 0xa8, 0x10, 0xf9, 0xf9, 0xa8, 0x10, 0xf9, 0xc5, 0xa8, + 0x10, 0xfd, 0x74, 0x54, 0x88, 0xfe, 0x72, 0x54, 0x88, 0xfc, 0x66, 0x54, 0x88, 0xfe, 0x76, 0x54, + 0x88, 0xfc, 0x6e, 0x54, 0x88, 0xfe, 0x7e, 0x54, 0x88, 0x7c, 0xf4, 0xbc, 0x10, 0xf9, 0xf8, 0x79, + 0x21, 0xfa, 0xc3, 0xe7, 0x85, 0xc8, 0x5f, 0x3c, 0x2f, 0x44, 0x7f, 0xf2, 0xbc, 0x10, 0xf9, 0xe9, + 0xf3, 0x42, 0xe4, 0x67, 0xcf, 0x0b, 0xd1, 0x4f, 0x9e, 0x17, 0xa2, 0x3f, 0x7f, 0x5e, 0x88, 0x7e, + 0xef, 0x6b, 0x57, 0xfd, 0x8f, 0x22, 0xd7, 0x1a, 0xec, 0xef, 0x4f, 0xd2, 0xeb, 0xf5, 0x95, 0xff, + 0x0d, 0x00, 0x00, 0xff, 0xff, 0xb2, 0x38, 0x26, 0xbd, 0xde, 0x3d, 0x00, 0x00, } From 3ff844c2e9398297e1af46810a432df63b4107ec Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 19 Feb 2019 14:24:15 +0100 Subject: [PATCH 28/40] cli: Add support for MACSettings_*Value types --- cmd/ttn-lw-cli/internal/util/flags.go | 69 ++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/cmd/ttn-lw-cli/internal/util/flags.go b/cmd/ttn-lw-cli/internal/util/flags.go index 7ee307253e..7955380bf5 100644 --- a/cmd/ttn-lw-cli/internal/util/flags.go +++ b/cmd/ttn-lw-cli/internal/util/flags.go @@ -26,6 +26,7 @@ import ( "github.com/gogo/protobuf/types" "github.com/spf13/pflag" "go.thethings.network/lorawan-stack/pkg/errors" + "go.thethings.network/lorawan-stack/pkg/ttnpb" ) var ( @@ -87,7 +88,7 @@ func isAtomicType(t reflect.Type, maskOnly bool) bool { } case "go.thethings.network/lorawan-stack/pkg/ttnpb": switch t.Name() { - case "Picture": + case "Picture", "MACSettings_DataRateIndexValue", "MACSettings_PingSlotPeriodValue", "MACSettings_AggregatedDutyCycleValue", "MACSettings_RxDelayValue": return true } } @@ -220,6 +221,33 @@ func addField(fs *pflag.FlagSet, name string, t reflect.Type, maskOnly bool) { case "BytesValue": fs.String(name, "", "(hex)") } + case "go.thethings.network/lorawan-stack/pkg/ttnpb": + switch t.Name() { + case "MACSettings_DataRateIndexValue": + values := make([]string, 0, len(proto.EnumValueMap("ttn.lorawan.v3.DataRateIndex"))) + for value := range proto.EnumValueMap("ttn.lorawan.v3.DataRateIndex") { + values = append(values, value) + } + fs.String(name, "", strings.Join(values, "|")) + case "MACSettings_PingSlotPeriodValue": + values := make([]string, 0, len(proto.EnumValueMap("ttn.lorawan.v3.PingSlotPeriod"))) + for value := range proto.EnumValueMap("ttn.lorawan.v3.PingSlotPeriod") { + values = append(values, value) + } + fs.String(name, "", strings.Join(values, "|")) + case "MACSettings_AggregatedDutyCycleValue": + values := make([]string, 0, len(proto.EnumValueMap("ttn.lorawan.v3.AggregatedDutyCycle"))) + for value := range proto.EnumValueMap("ttn.lorawan.v3.AggregatedDutyCycle") { + values = append(values, value) + } + fs.String(name, "", strings.Join(values, "|")) + case "MACSettings_RxDelayValue": + values := make([]string, 0, len(proto.EnumValueMap("ttn.lorawan.v3.RxDelay"))) + for value := range proto.EnumValueMap("ttn.lorawan.v3.RxDelay") { + values = append(values, value) + } + fs.String(name, "", strings.Join(values, "|")) + } default: fmt.Printf("flags: %s.%s not yet supported (%s)\n", t.PkgPath(), t.Name(), name) } @@ -403,6 +431,45 @@ func setField(rv reflect.Value, path []string, v reflect.Value) error { } field.Set(reflect.ValueOf(types.BytesValue{Value: buf})) } + case ft.PkgPath() == "go.thethings.network/lorawan-stack/pkg/ttnpb": + switch ft.Name() { + case "MACSettings_DataRateIndexValue": + if enumValue, ok := proto.EnumValueMap("ttn.lorawan.v3.DataRateIndex")[v.String()]; ok { + field.Set(reflect.ValueOf(ttnpb.MACSettings_DataRateIndexValue{Value: ttnpb.DataRateIndex(enumValue)})) + break + } + + var enum ttnpb.DataRateIndex + if err := enum.UnmarshalText([]byte(v.String())); err != nil { + field.Set(reflect.ValueOf(ttnpb.MACSettings_DataRateIndexValue{Value: enum})) + break + } + return fmt.Errorf(`invalid value "%s" for %s`, v.String(), ft.Name()) + case "MACSettings_PingSlotPeriodValue": + if enumValue, ok := proto.EnumValueMap("ttn.lorawan.v3.PingSlotPeriod")[v.String()]; ok { + field.Set(reflect.ValueOf(ttnpb.MACSettings_PingSlotPeriodValue{Value: ttnpb.PingSlotPeriod(enumValue)})) + break + } + return fmt.Errorf(`invalid value "%s" for %s`, v.String(), ft.Name()) + case "MACSettings_AggregatedDutyCycleValue": + if enumValue, ok := proto.EnumValueMap("ttn.lorawan.v3.AggregatedDutyCycle")[v.String()]; ok { + field.Set(reflect.ValueOf(ttnpb.MACSettings_AggregatedDutyCycleValue{Value: ttnpb.AggregatedDutyCycle(enumValue)})) + break + } + return fmt.Errorf(`invalid value "%s" for %s`, v.String(), ft.Name()) + case "MACSettings_RxDelayValue": + if enumValue, ok := proto.EnumValueMap("ttn.lorawan.v3.RxDelay")[v.String()]; ok { + field.Set(reflect.ValueOf(ttnpb.MACSettings_RxDelayValue{Value: ttnpb.RxDelay(enumValue)})) + break + } + + var enum ttnpb.RxDelay + if err := enum.UnmarshalText([]byte(v.String())); err != nil { + field.Set(reflect.ValueOf(ttnpb.MACSettings_RxDelayValue{Value: enum})) + break + } + return fmt.Errorf(`invalid value "%s" for %s`, v.String(), ft.Name()) + } case ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && vt.Kind() == reflect.String: s := strings.TrimPrefix(v.String(), "0x") buf, err := hex.DecodeString(s) From 994bb2e712cc417932b322515295707dcd8e3ccb Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Tue, 19 Feb 2019 20:18:42 +0100 Subject: [PATCH 29/40] ns: Use DevAddr from session --- pkg/networkserver/downlink.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/networkserver/downlink.go b/pkg/networkserver/downlink.go index 2686ccf4dc..7906776558 100644 --- a/pkg/networkserver/downlink.go +++ b/pkg/networkserver/downlink.go @@ -234,7 +234,7 @@ outer: } var err error - cmdBuf, err = crypto.EncryptDownlink(key, *dev.EndDeviceIdentifiers.DevAddr, pld.FHDR.FCnt, cmdBuf) + cmdBuf, err = crypto.EncryptDownlink(key, dev.Session.DevAddr, pld.FHDR.FCnt, cmdBuf) if err != nil { return nil, nil, errEncryptMAC.WithCause(err) } @@ -300,7 +300,7 @@ outer: if dev.MACState.LoRaWANVersion.Compare(ttnpb.MAC_V1_1) < 0 { mic, err = crypto.ComputeLegacyDownlinkMIC( key, - *dev.EndDeviceIdentifiers.DevAddr, + dev.Session.DevAddr, pld.FHDR.FCnt, b, ) @@ -311,7 +311,7 @@ outer: } mic, err = crypto.ComputeDownlinkMIC( key, - *dev.EndDeviceIdentifiers.DevAddr, + dev.Session.DevAddr, confFCnt, pld.FHDR.FCnt, b, From 284ad74c7b9587ff1a4134ead30de7064a931dde Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 20 Feb 2019 09:56:12 +0100 Subject: [PATCH 30/40] ci: Run `make messages` in `go.lint` --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 409110851b..2d0af82b25 100644 --- a/.travis.yml +++ b/.travis.yml @@ -100,6 +100,7 @@ script: make go.fmt make go.misspell make headers.check + make messages fi - | if [[ "$RUNTYPE" == "go.lint-extra" ]]; then From 8c1699eac4d23a5b89329dab47ada0e6dd8f7adc Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 20 Feb 2019 09:56:22 +0100 Subject: [PATCH 31/40] dev: Regenerate messages --- config/messages.json | 45 +++++++++----------------------------------- 1 file changed, 9 insertions(+), 36 deletions(-) diff --git a/config/messages.json b/config/messages.json index 4420538519..bf2bfdd081 100644 --- a/config/messages.json +++ b/config/messages.json @@ -3626,15 +3626,6 @@ "file": "registry.go" } }, - "error:pkg/networkserver:adr_margin": { - "translations": { - "en": "invalid ADR margin" - }, - "description": { - "package": "pkg/networkserver", - "file": "errors.go" - } - }, "error:pkg/networkserver:channel_index": { "translations": { "en": "invalid channel index" @@ -3653,24 +3644,6 @@ "file": "errors.go" } }, - "error:pkg/networkserver:class_b_timeout": { - "translations": { - "en": "invalid class B timeout" - }, - "description": { - "package": "pkg/networkserver", - "file": "errors.go" - } - }, - "error:pkg/networkserver:class_c_timeout": { - "translations": { - "en": "invalid class C timeout" - }, - "description": { - "package": "pkg/networkserver", - "file": "errors.go" - } - }, "error:pkg/networkserver:compute_mic": { "translations": { "en": "failed to compute MIC" @@ -3833,6 +3806,15 @@ "file": "errors.go" } }, + "error:pkg/networkserver:field_value": { + "translations": { + "en": "invalid value of field `{field}`" + }, + "description": { + "package": "pkg/networkserver", + "file": "errors.go" + } + }, "error:pkg/networkserver:gateway_server_not_found": { "translations": { "en": "Gateway Server not found" @@ -3914,15 +3896,6 @@ "file": "errors.go" } }, - "error:pkg/networkserver:no_mac_settings": { - "translations": { - "en": "no mac settings specified" - }, - "description": { - "package": "pkg/networkserver", - "file": "errors.go" - } - }, "error:pkg/networkserver:no_payload": { "translations": { "en": "no message payload specified" From a857a6f852a8d5390390ac051570e7f1857880a7 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 20 Feb 2019 17:45:16 +0100 Subject: [PATCH 32/40] ns: Use cryptoutil.UnwrapAES128Key --- pkg/networkserver/downlink.go | 32 +++++++----------------- pkg/networkserver/grpc_gsns.go | 45 ++++++++++------------------------ 2 files changed, 22 insertions(+), 55 deletions(-) diff --git a/pkg/networkserver/downlink.go b/pkg/networkserver/downlink.go index 7906776558..e35384c083 100644 --- a/pkg/networkserver/downlink.go +++ b/pkg/networkserver/downlink.go @@ -24,12 +24,12 @@ import ( "github.com/mohae/deepcopy" "go.thethings.network/lorawan-stack/pkg/cluster" "go.thethings.network/lorawan-stack/pkg/crypto" + "go.thethings.network/lorawan-stack/pkg/crypto/cryptoutil" "go.thethings.network/lorawan-stack/pkg/encoding/lorawan" "go.thethings.network/lorawan-stack/pkg/errors" "go.thethings.network/lorawan-stack/pkg/events" "go.thethings.network/lorawan-stack/pkg/log" "go.thethings.network/lorawan-stack/pkg/ttnpb" - "go.thethings.network/lorawan-stack/pkg/types" "go.thethings.network/lorawan-stack/pkg/unique" ) @@ -220,20 +220,12 @@ outer: if dev.Session.NwkSEncKey == nil || len(dev.Session.NwkSEncKey.Key) == 0 { return nil, nil, errUnknownNwkSEncKey } - - var key types.AES128Key - if dev.Session.NwkSEncKey.KEKLabel != "" { - b, err := ns.KeyVault.Unwrap(dev.Session.NwkSEncKey.Key, dev.Session.NwkSEncKey.KEKLabel) - if err != nil { - logger.WithField("kek_label", dev.Session.NwkSEncKey.KEKLabel).WithError(err).Error("Failed to unwrap NwkSEncKey") - return nil, nil, err - } - copy(key[:], b) - } else { - copy(key[:], dev.Session.NwkSEncKey.Key[:]) + key, err := cryptoutil.UnwrapAES128Key(*dev.Session.NwkSEncKey, ns.KeyVault) + if err != nil { + logger.WithField("kek_label", dev.Session.NwkSEncKey.KEKLabel).WithError(err).Error("Failed to unwrap NwkSEncKey") + return nil, nil, err } - var err error cmdBuf, err = crypto.EncryptDownlink(key, dev.Session.DevAddr, pld.FHDR.FCnt, cmdBuf) if err != nil { return nil, nil, errEncryptMAC.WithCause(err) @@ -281,19 +273,13 @@ outer: } // NOTE: It is assumed, that b does not contain MIC. - var key types.AES128Key if dev.Session.SNwkSIntKey == nil || len(dev.Session.SNwkSIntKey.Key) == 0 { return nil, nil, errUnknownSNwkSIntKey } - if dev.Session.SNwkSIntKey.KEKLabel != "" { - b, err := ns.KeyVault.Unwrap(dev.Session.SNwkSIntKey.Key, dev.Session.SNwkSIntKey.KEKLabel) - if err != nil { - logger.WithField("kek_label", dev.Session.SNwkSIntKey.KEKLabel).WithError(err).Error("Failed to unwrap SNwkSIntKey") - return nil, nil, err - } - copy(key[:], b) - } else { - copy(key[:], dev.Session.SNwkSIntKey.Key[:]) + key, err := cryptoutil.UnwrapAES128Key(*dev.Session.SNwkSIntKey, ns.KeyVault) + if err != nil { + logger.WithField("kek_label", dev.Session.SNwkSIntKey.KEKLabel).WithError(err).Error("Failed to unwrap SNwkSIntKey") + return nil, nil, err } var mic [4]byte diff --git a/pkg/networkserver/grpc_gsns.go b/pkg/networkserver/grpc_gsns.go index bdf2914b76..0a73e6cc2e 100644 --- a/pkg/networkserver/grpc_gsns.go +++ b/pkg/networkserver/grpc_gsns.go @@ -27,6 +27,7 @@ import ( "github.com/mohae/deepcopy" clusterauth "go.thethings.network/lorawan-stack/pkg/auth/cluster" "go.thethings.network/lorawan-stack/pkg/crypto" + "go.thethings.network/lorawan-stack/pkg/crypto/cryptoutil" "go.thethings.network/lorawan-stack/pkg/encoding/lorawan" "go.thethings.network/lorawan-stack/pkg/errors" "go.thethings.network/lorawan-stack/pkg/events" @@ -278,20 +279,13 @@ outer: continue } - var fNwkSIntKey types.AES128Key - if dev.matchedSession.FNwkSIntKey.KEKLabel != "" { - b, err := ns.Component.KeyVault.Unwrap(dev.matchedSession.FNwkSIntKey.Key, dev.matchedSession.FNwkSIntKey.KEKLabel) - if err != nil { - logger.WithField("kek_label", dev.matchedSession.FNwkSIntKey.KEKLabel).WithError(err).Error("Failed to unwrap FNwkSIntKey, skipping...") - continue - } - copy(fNwkSIntKey[:], b) - } else { - copy(fNwkSIntKey[:], dev.matchedSession.FNwkSIntKey.Key[:]) + fNwkSIntKey, err := cryptoutil.UnwrapAES128Key(*dev.matchedSession.FNwkSIntKey, ns.KeyVault) + if err != nil { + logger.WithField("kek_label", dev.matchedSession.FNwkSIntKey.KEKLabel).WithError(err).Error("Failed to unwrap FNwkSIntKey, skipping...") + continue } var computedMIC [4]byte - var err error if dev.MACState.LoRaWANVersion.Compare(ttnpb.MAC_V1_1) < 0 { computedMIC, err = crypto.ComputeLegacyUplinkMIC( fNwkSIntKey, @@ -305,16 +299,10 @@ outer: continue } - var sNwkSIntKey types.AES128Key - if dev.matchedSession.SNwkSIntKey.KEKLabel != "" { - b, err := ns.Component.KeyVault.Unwrap(dev.matchedSession.SNwkSIntKey.Key, dev.matchedSession.SNwkSIntKey.KEKLabel) - if err != nil { - logger.WithField("kek_label", dev.matchedSession.SNwkSIntKey.KEKLabel).WithError(err).Error("Failed to unwrap SNwkSIntKey, skipping...") - continue - } - copy(sNwkSIntKey[:], b) - } else { - copy(sNwkSIntKey[:], dev.matchedSession.SNwkSIntKey.Key[:]) + sNwkSIntKey, err := cryptoutil.UnwrapAES128Key(*dev.matchedSession.SNwkSIntKey, ns.KeyVault) + if err != nil { + logger.WithField("kek_label", dev.matchedSession.SNwkSIntKey.KEKLabel).WithError(err).Error("Failed to unwrap SNwkSIntKey, skipping...") + continue } var confFCnt uint32 @@ -433,17 +421,10 @@ func (ns *NetworkServer) handleUplink(ctx context.Context, up *ttnpb.UplinkMessa if ses.NwkSEncKey == nil || len(ses.NwkSEncKey.Key) == 0 { return errUnknownNwkSEncKey } - - var key types.AES128Key - if ses.NwkSEncKey.KEKLabel != "" { - b, err := ns.Component.KeyVault.Unwrap(ses.NwkSEncKey.Key, ses.NwkSEncKey.KEKLabel) - if err != nil { - logger.WithField("kek_label", ses.NwkSEncKey.KEKLabel).WithError(err).Error("Failed to unwrap NwkSEncKey") - return err - } - copy(key[:], b) - } else { - copy(key[:], ses.NwkSEncKey.Key[:]) + key, err := cryptoutil.UnwrapAES128Key(*ses.NwkSEncKey, ns.KeyVault) + if err != nil { + logger.WithField("kek_label", ses.NwkSEncKey.KEKLabel).WithError(err).Error("Failed to unwrap NwkSEncKey") + return err } mac, err = crypto.DecryptUplink(key, pld.DevAddr, pld.FCnt, mac) From 5b2026bf9292bc7d16b66e13166297a11cae7723 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 20 Feb 2019 18:05:22 +0100 Subject: [PATCH 33/40] ns: Improve readability --- pkg/networkserver/grpc_deviceregistry.go | 23 ++++++------- pkg/networkserver/mac_dev_status.go | 41 +++++++++++++++--------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/pkg/networkserver/grpc_deviceregistry.go b/pkg/networkserver/grpc_deviceregistry.go index 5d1298f6c5..caf908d145 100644 --- a/pkg/networkserver/grpc_deviceregistry.go +++ b/pkg/networkserver/grpc_deviceregistry.go @@ -43,6 +43,15 @@ func validABPSessionKey(key *ttnpb.KeyEnvelope) bool { // Set implements NsEndDeviceRegistryServer. func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest) (*ttnpb.EndDevice, error) { + if err := ttnpb.ProhibitFields(req.FieldMask.Paths, + "mac_state.current_parameters", + "mac_state.desired_parameters", + "pending_session", + "session.keys.app_s_key", + ); err != nil { + return nil, errInvalidFieldMask.WithCause(err) + } + if err := rights.RequireApplication(ctx, req.Device.ApplicationIdentifiers, ttnpb.RIGHT_APPLICATION_DEVICES_WRITE); err != nil { return nil, err } @@ -63,14 +72,6 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest var addDownlinkTask bool dev, err := ns.devices.SetByID(ctx, req.Device.EndDeviceIdentifiers.ApplicationIdentifiers, req.Device.EndDeviceIdentifiers.DeviceID, gets, func(dev *ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error) { - if err := ttnpb.ProhibitFields(req.FieldMask.Paths, - "mac_state.current_parameters", - "mac_state.desired_parameters", - "pending_session", - ); err != nil { - return nil, nil, errInvalidFieldMask.WithCause(err) - } - if dev != nil { if err := ttnpb.ProhibitFields(req.FieldMask.Paths, "session", @@ -110,12 +111,6 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.nwk_s_enc_key.kek_label") && (req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetNwkSEncKey().GetKEKLabel()) == 0) { return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.nwk_s_enc_key.kek_label") } - if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.app_s_key.key") && (req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetAppSKey().GetKey()) == 0) { - return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.app_s_key.key") - } - if ttnpb.HasAnyField(req.FieldMask.Paths, "session.keys.app_s_key.kek_label") && (req.Device.Session == nil || len(req.Device.Session.SessionKeys.GetAppSKey().GetKEKLabel()) == 0) { - return nil, nil, errInvalidFieldValue.WithAttributes("field", "session.keys.app_s_key.kek_label") - } if ttnpb.HasAnyField(req.FieldMask.Paths, "mac_settings.class_b_timeout") && req.Device.GetMACSettings().GetClassBTimeout() == nil { return nil, nil, errInvalidFieldValue.WithAttributes("field", "mac_settings.class_b_timeout") diff --git a/pkg/networkserver/mac_dev_status.go b/pkg/networkserver/mac_dev_status.go index 3544d440dc..7e3cc15a80 100644 --- a/pkg/networkserver/mac_dev_status.go +++ b/pkg/networkserver/mac_dev_status.go @@ -32,25 +32,36 @@ const ( DefaultStatusTimePeriodicity = time.Hour ) -func enqueueDevStatusReq(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, maxUpLen uint16, defaults ttnpb.MACSettings) (uint16, uint16, bool) { - cp := DefaultStatusCountPeriodicity - if dev.GetMACSettings().GetStatusCountPeriodicity() != nil { - cp = dev.MACSettings.StatusCountPeriodicity.Value - } else if defaults.StatusCountPeriodicity != nil { - cp = defaults.StatusCountPeriodicity.Value +func deviceStatusCountPeriodicity(dev *ttnpb.EndDevice, defaults ttnpb.MACSettings) uint32 { + if dev.MACSettings != nil && dev.MACSettings.StatusCountPeriodicity != nil { + return dev.MACSettings.StatusCountPeriodicity.Value + } + if defaults.StatusCountPeriodicity != nil { + return defaults.StatusCountPeriodicity.Value } + return DefaultStatusCountPeriodicity +} - tp := DefaultStatusTimePeriodicity - if dev.GetMACSettings().GetStatusTimePeriodicity() != nil { - tp = *dev.MACSettings.StatusTimePeriodicity - } else if defaults.StatusCountPeriodicity != nil { - tp = *defaults.StatusTimePeriodicity +func deviceStatusTimePeriodicity(dev *ttnpb.EndDevice, defaults ttnpb.MACSettings) time.Duration { + if dev.MACSettings != nil && dev.MACSettings.StatusTimePeriodicity != nil { + return *dev.MACSettings.StatusTimePeriodicity } + if defaults.StatusTimePeriodicity != nil { + return *defaults.StatusTimePeriodicity + } + return DefaultStatusTimePeriodicity +} - if cp == 0 && tp == 0 || - dev.LastDevStatusReceivedAt != nil && - (cp == 0 || dev.MACState.LastDevStatusFCntUp+cp > dev.Session.LastFCntUp) && - (tp == 0 || dev.LastDevStatusReceivedAt.Add(tp).After(time.Now())) { +func enqueueDevStatusReq(ctx context.Context, dev *ttnpb.EndDevice, maxDownLen, maxUpLen uint16, defaults ttnpb.MACSettings) (uint16, uint16, bool) { + cp := deviceStatusCountPeriodicity(dev, defaults) + tp := deviceStatusTimePeriodicity(dev, defaults) + + if cp == 0 && tp == 0 { + return maxDownLen, maxUpLen, true + } + if dev.LastDevStatusReceivedAt != nil && + (cp == 0 || dev.MACState.LastDevStatusFCntUp+cp > dev.Session.LastFCntUp) && + (tp == 0 || dev.LastDevStatusReceivedAt.Add(tp).After(time.Now())) { return maxDownLen, maxUpLen, true } From 68e642724a3b54cb7546e192fb529ded5eae5c2a Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 20 Feb 2019 18:33:25 +0100 Subject: [PATCH 34/40] ns: Add MACSettingConfig --- cmd/internal/shared/networkserver/config.go | 14 ++++++----- pkg/networkserver/config.go | 28 ++++++++++++--------- pkg/networkserver/downlink_internal_test.go | 20 +++++++++------ pkg/networkserver/networkserver.go | 18 ++++++------- 4 files changed, 45 insertions(+), 35 deletions(-) diff --git a/cmd/internal/shared/networkserver/config.go b/cmd/internal/shared/networkserver/config.go index d025115134..49a129b8b1 100644 --- a/cmd/internal/shared/networkserver/config.go +++ b/cmd/internal/shared/networkserver/config.go @@ -30,10 +30,12 @@ var DefaultNetworkServerConfig = networkserver.Config{ MACCommands: "highest", MaxApplicationDownlink: "high", }, - DefaultADRMargin: func(v float32) *float32 { return &v }(networkserver.DefaultADRMargin), - DefaultRx1Delay: func(v ttnpb.RxDelay) *ttnpb.RxDelay { return &v }(ttnpb.RX_DELAY_5), - DefaultClassBTimeout: func(v time.Duration) *time.Duration { return &v }(time.Minute), - DefaultClassCTimeout: func(v time.Duration) *time.Duration { return &v }(networkserver.DefaultClassCTimeout), - DefaultStatusTimePeriodicity: func(v time.Duration) *time.Duration { return &v }(networkserver.DefaultStatusTimePeriodicity), - DefaultStatusCountPeriodicity: func(v uint32) *uint32 { return &v }(networkserver.DefaultStatusCountPeriodicity), + DefaultMACSettings: networkserver.MACSettingConfig{ + ADRMargin: func(v float32) *float32 { return &v }(networkserver.DefaultADRMargin), + Rx1Delay: func(v ttnpb.RxDelay) *ttnpb.RxDelay { return &v }(ttnpb.RX_DELAY_5), + ClassBTimeout: func(v time.Duration) *time.Duration { return &v }(time.Minute), + ClassCTimeout: func(v time.Duration) *time.Duration { return &v }(networkserver.DefaultClassCTimeout), + StatusTimePeriodicity: func(v time.Duration) *time.Duration { return &v }(networkserver.DefaultStatusTimePeriodicity), + StatusCountPeriodicity: func(v uint32) *uint32 { return &v }(networkserver.DefaultStatusCountPeriodicity), + }, } diff --git a/pkg/networkserver/config.go b/pkg/networkserver/config.go index 7ac9daee87..afbf1c181a 100644 --- a/pkg/networkserver/config.go +++ b/pkg/networkserver/config.go @@ -24,18 +24,22 @@ import ( // Config represents the NetworkServer configuration. type Config struct { - Devices DeviceRegistry `name:"-"` - DownlinkTasks DownlinkTaskQueue `name:"-"` - DeduplicationWindow time.Duration `name:"deduplication-window" description:"Time window during which, duplicate messages are collected for metadata"` - CooldownWindow time.Duration `name:"cooldown-window" description:"Time window starting right after deduplication window, during which, duplicate messages are discarded"` - DownlinkPriorities DownlinkPriorityConfig `name:"downlink-priorities" description:"Downlink message priorities"` - NetID types.NetID `name:"net_id" description:"NetID of this Network Server"` - DefaultADRMargin *float32 `name:"default-adr-margin" description:"The default margin Network Server should add in ADR requests if not configured in device's MAC settings"` - DefaultRx1Delay *ttnpb.RxDelay `name:"default-rx1-delay" description:"Rx1Delay value Network Server should use if not configured in device's MAC settings"` - DefaultClassBTimeout *time.Duration `name:"default-class-b-timeout" description:"Deadline for a device in class B mode to respond to requests from the Network Server if not configured in device's MAC settings"` - DefaultClassCTimeout *time.Duration `name:"default-class-c-timeout" description:"Deadline for a device in class C mode to respond to requests from the Network Server if not configured in device's MAC settings"` - DefaultStatusTimePeriodicity *time.Duration `name:"default-status-time-periodicity" description:"The interval after which a DevStatusReq MACCommand shall be sent by Network Server if not configured in device's MAC settings"` - DefaultStatusCountPeriodicity *uint32 `name:"default-status-count-periodicity" description:"Number of uplink messages after which a DevStatusReq MACCommand shall be sent by Network Server if not configured in device's MAC settings"` + Devices DeviceRegistry `name:"-"` + DownlinkTasks DownlinkTaskQueue `name:"-"` + NetID types.NetID `name:"net_id" description:"NetID of this Network Server"` + DeduplicationWindow time.Duration `name:"deduplication-window" description:"Time window during which, duplicate messages are collected for metadata"` + CooldownWindow time.Duration `name:"cooldown-window" description:"Time window starting right after deduplication window, during which, duplicate messages are discarded"` + DownlinkPriorities DownlinkPriorityConfig `name:"downlink-priorities" description:"Downlink message priorities"` + DefaultMACSettings MACSettingConfig `name:"default-mac-settings" description:"Default MAC settings to fallback to if not specified by device, band or frequency plan"` +} + +type MACSettingConfig struct { + ADRMargin *float32 `name:"adr-margin" description:"The default margin Network Server should add in ADR requests if not configured in device's MAC settings"` + Rx1Delay *ttnpb.RxDelay `name:"rx1-delay" description:"Rx1Delay value Network Server should use if not configured in device's MAC settings"` + ClassBTimeout *time.Duration `name:"class-b-timeout" description:"Deadline for a device in class B mode to respond to requests from the Network Server if not configured in device's MAC settings"` + ClassCTimeout *time.Duration `name:"class-c-timeout" description:"Deadline for a device in class C mode to respond to requests from the Network Server if not configured in device's MAC settings"` + StatusTimePeriodicity *time.Duration `name:"status-time-periodicity" description:"The interval after which a DevStatusReq MACCommand shall be sent by Network Server if not configured in device's MAC settings"` + StatusCountPeriodicity *uint32 `name:"status-count-periodicity" description:"Number of uplink messages after which a DevStatusReq MACCommand shall be sent by Network Server if not configured in device's MAC settings"` } // DownlinkPriorityConfig defines priorities for downlink messages. diff --git a/pkg/networkserver/downlink_internal_test.go b/pkg/networkserver/downlink_internal_test.go index b9085cb851..b9beae51e9 100644 --- a/pkg/networkserver/downlink_internal_test.go +++ b/pkg/networkserver/downlink_internal_test.go @@ -2528,8 +2528,10 @@ func TestProcessDownlinkTask(t *testing.T) { Devices: &MockDeviceRegistry{ SetByIDFunc: tc.SetByIDFunc, }, - DefaultStatusTimePeriodicity: DurationPtr(0), - DefaultStatusCountPeriodicity: func(v uint32) *uint32 { return &v }(0), + DefaultMACSettings: MACSettingConfig{ + StatusTimePeriodicity: DurationPtr(0), + StatusCountPeriodicity: func(v uint32) *uint32 { return &v }(0), + }, }, )).(*NetworkServer) ns.FrequencyPlans = frequencyplans.NewStore(test.FrequencyPlansFetcher) @@ -3493,12 +3495,14 @@ func TestGenerateDownlink(t *testing.T) { &component.Config{}, ), &Config{ - DeduplicationWindow: 42, - CooldownWindow: 42, - DownlinkTasks: &MockDownlinkTaskQueue{}, - Devices: &MockDeviceRegistry{}, - DefaultStatusTimePeriodicity: DurationPtr(0), - DefaultStatusCountPeriodicity: func(v uint32) *uint32 { return &v }(0), + DeduplicationWindow: 42, + CooldownWindow: 42, + DownlinkTasks: &MockDownlinkTaskQueue{}, + Devices: &MockDeviceRegistry{}, + DefaultMACSettings: MACSettingConfig{ + StatusTimePeriodicity: DurationPtr(0), + StatusCountPeriodicity: func(v uint32) *uint32 { return &v }(0), + }, }, )).(*NetworkServer) ns.FrequencyPlans = frequencyplans.NewStore(test.FrequencyPlansFetcher) diff --git a/pkg/networkserver/networkserver.go b/pkg/networkserver/networkserver.go index ddf422766d..0ea22cf845 100644 --- a/pkg/networkserver/networkserver.go +++ b/pkg/networkserver/networkserver.go @@ -210,9 +210,9 @@ func New(c *component.Component, conf *Config, opts ...Option) (*NetworkServer, downlinkTasks: conf.DownlinkTasks, downlinkPriorities: downlinkPriorities, defaultMACSettings: ttnpb.MACSettings{ - ClassBTimeout: conf.DefaultClassBTimeout, - ClassCTimeout: conf.DefaultClassCTimeout, - StatusTimePeriodicity: conf.DefaultStatusTimePeriodicity, + ClassBTimeout: conf.DefaultMACSettings.ClassBTimeout, + ClassCTimeout: conf.DefaultMACSettings.ClassCTimeout, + StatusTimePeriodicity: conf.DefaultMACSettings.StatusTimePeriodicity, }, } ns.hashPool.New = func() interface{} { @@ -222,14 +222,14 @@ func New(c *component.Component, conf *Config, opts ...Option) (*NetworkServer, return &metadataAccumulator{} } - if conf.DefaultADRMargin != nil { - ns.defaultMACSettings.ADRMargin = &pbtypes.FloatValue{Value: *conf.DefaultADRMargin} + if conf.DefaultMACSettings.ADRMargin != nil { + ns.defaultMACSettings.ADRMargin = &pbtypes.FloatValue{Value: *conf.DefaultMACSettings.ADRMargin} } - if conf.DefaultRx1Delay != nil { - ns.defaultMACSettings.Rx1Delay = &ttnpb.MACSettings_RxDelayValue{Value: *conf.DefaultRx1Delay} + if conf.DefaultMACSettings.Rx1Delay != nil { + ns.defaultMACSettings.Rx1Delay = &ttnpb.MACSettings_RxDelayValue{Value: *conf.DefaultMACSettings.Rx1Delay} } - if conf.DefaultStatusCountPeriodicity != nil { - ns.defaultMACSettings.StatusCountPeriodicity = &pbtypes.UInt32Value{Value: *conf.DefaultStatusCountPeriodicity} + if conf.DefaultMACSettings.StatusCountPeriodicity != nil { + ns.defaultMACSettings.StatusCountPeriodicity = &pbtypes.UInt32Value{Value: *conf.DefaultMACSettings.StatusCountPeriodicity} } for _, opt := range opts { From 0a8c2028e880386fde73aac35be74adad4b9a339 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 20 Feb 2019 10:38:47 +0100 Subject: [PATCH 35/40] ns: Make EUIs optional for ABP devices, validate for OTAA --- config/messages.json | 18 ++++++++++++++++++ pkg/networkserver/errors.go | 2 ++ pkg/networkserver/grpc_deviceregistry.go | 14 ++++++-------- pkg/networkserver/redis/registry.go | 6 +----- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/config/messages.json b/config/messages.json index bf2bfdd081..c2c1d17a3c 100644 --- a/config/messages.json +++ b/config/messages.json @@ -3869,6 +3869,15 @@ "file": "errors.go" } }, + "error:pkg/networkserver:no_dev_eui": { + "translations": { + "en": "no DevEUI specified" + }, + "description": { + "package": "pkg/networkserver", + "file": "errors.go" + } + }, "error:pkg/networkserver:no_downlink": { "translations": { "en": "no downlink to send" @@ -3896,6 +3905,15 @@ "file": "errors.go" } }, + "error:pkg/networkserver:no_join_eui": { + "translations": { + "en": "no JoinEUI specified" + }, + "description": { + "package": "pkg/networkserver", + "file": "errors.go" + } + }, "error:pkg/networkserver:no_payload": { "translations": { "en": "no message payload specified" diff --git a/pkg/networkserver/errors.go b/pkg/networkserver/errors.go index a134b359a7..13e71ad33b 100644 --- a/pkg/networkserver/errors.go +++ b/pkg/networkserver/errors.go @@ -48,6 +48,8 @@ var ( errJoinServerNotFound = errors.DefineNotFound("join_server_not_found", "Join Server not found") errMACRequestNotFound = errors.DefineInvalidArgument("mac_request_not_found", "MAC response received, but corresponding request not found") errNoFrequencyPlan = errors.DefineInvalidArgument("no_frequency_plan", "no frequency plan specified") + errNoDevEUI = errors.DefineInvalidArgument("no_dev_eui", "no DevEUI specified") + errNoJoinEUI = errors.DefineInvalidArgument("no_join_eui", "no JoinEUI specified") errNoPath = errors.DefineNotFound("no_downlink_path", "no downlink path available") errNoPayload = errors.DefineInvalidArgument("no_payload", "no message payload specified") errNoRekey = errors.DefineInvalidArgument("no_rekey", "rekey not received after join-accept") diff --git a/pkg/networkserver/grpc_deviceregistry.go b/pkg/networkserver/grpc_deviceregistry.go index caf908d145..fc35dd327d 100644 --- a/pkg/networkserver/grpc_deviceregistry.go +++ b/pkg/networkserver/grpc_deviceregistry.go @@ -17,7 +17,6 @@ package networkserver import ( "bytes" "context" - "strings" "time" pbtypes "github.com/gogo/protobuf/types" @@ -215,14 +214,13 @@ func (ns *NetworkServer) Set(ctx context.Context, req *ttnpb.SetEndDeviceRequest } if req.Device.SupportsJoin { - var hasSession bool - for _, p := range sets { - if p == "session" || strings.HasPrefix(p, "session.") { - hasSession = true - break - } + if req.Device.EndDeviceIdentifiers.JoinEUI == nil { + return nil, nil, errNoJoinEUI } - if !hasSession { + if req.Device.EndDeviceIdentifiers.DevEUI == nil { + return nil, nil, errNoDevEUI + } + if !ttnpb.HasAnyField([]string{"session"}, sets...) { return &req.Device, sets, nil } } diff --git a/pkg/networkserver/redis/registry.go b/pkg/networkserver/redis/registry.go index 4b5e4988d5..eca2ed82b4 100644 --- a/pkg/networkserver/redis/registry.go +++ b/pkg/networkserver/redis/registry.go @@ -215,11 +215,7 @@ func (r *DeviceRegistry) SetByID(ctx context.Context, appID ttnpb.ApplicationIde } f = func(p redis.Pipeliner) error { - if create { - if newIDs.JoinEUI == nil || newIDs.DevEUI == nil { - return errInvalidIdentifiers - } - + if create && newIDs.JoinEUI != nil && newIDs.DevEUI != nil { ek := r.Redis.Key(euiKey, newIDs.JoinEUI.String(), newIDs.DevEUI.String()) if err := tx.Watch(ek).Err(); err != nil { return err From cd2452a2e6899717874f53e554ff1c3ee5e1cde4 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 20 Feb 2019 18:46:20 +0100 Subject: [PATCH 36/40] ns: Fix t.Fatal usage in registry tests --- pkg/networkserver/grpc_deviceregistry_test.go | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/pkg/networkserver/grpc_deviceregistry_test.go b/pkg/networkserver/grpc_deviceregistry_test.go index a84c3cf7fb..29f946cf06 100644 --- a/pkg/networkserver/grpc_deviceregistry_test.go +++ b/pkg/networkserver/grpc_deviceregistry_test.go @@ -16,6 +16,7 @@ package networkserver_test import ( "context" + "fmt" "testing" "time" @@ -67,8 +68,9 @@ func TestDeviceRegistryGet(t *testing.T) { }) }, GetByIDFunc: func(ctx context.Context, appID ttnpb.ApplicationIdentifiers, devID string, paths []string) (*ttnpb.EndDevice, error) { - test.MustTFromContext(ctx).Fatal("GetByIDFunc must not be called") - panic("Unreachable") + err := errors.New("GetByIDFunc must not be called") + test.MustTFromContext(ctx).Error(err) + return nil, err }, Request: &ttnpb.GetEndDeviceRequest{ EndDeviceIdentifiers: ids, @@ -210,8 +212,9 @@ func TestDeviceRegistrySet(t *testing.T) { }) }, SetByIDFunc: func(ctx context.Context, appID ttnpb.ApplicationIdentifiers, devID string, gets []string, f func(*ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error)) (*ttnpb.EndDevice, error) { - test.MustTFromContext(ctx).Fatal("SetByIDFunc must not be called") - panic("Unreachable") + err := errors.New("SetByIDFunc must not be called") + test.MustTFromContext(ctx).Error(err) + return nil, err }, Request: &ttnpb.SetEndDeviceRequest{ Device: ttnpb.EndDevice{ @@ -277,7 +280,9 @@ func TestDeviceRegistrySet(t *testing.T) { }) dev, sets, err := f(nil) - a.So(err, should.BeNil) + if !a.So(err, should.BeNil) { + return nil, err + } a.So(sets, should.HaveSameElementsDeep, []string{ "frequency_plan_id", "lorawan_phy_version", @@ -380,7 +385,9 @@ func TestDeviceRegistrySet(t *testing.T) { }) dev, sets, err := f(nil) - a.So(err, should.BeNil) + if !a.So(err, should.BeNil) { + return nil, err + } a.So(sets, should.HaveSameElementsDeep, []string{ "frequency_plan_id", "lorawan_phy_version", @@ -446,7 +453,7 @@ func TestDeviceRegistrySet(t *testing.T) { } err = ResetMACState(expected, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{}) if !a.So(err, should.BeNil) { - t.Fatalf("Failed to reset MAC state: %s", err) + panic(fmt.Sprintf("Failed to reset MAC state: %s", err)) } a.So(dev, should.Resemble, expected) return dev, nil @@ -544,7 +551,7 @@ func TestDeviceRegistrySet(t *testing.T) { }, } if err := ResetMACState(expected, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{}); err != nil { - t.Fatalf("Failed to reset MAC state: %s", err) + panic(fmt.Sprintf("Failed to reset MAC state: %s", err)) } return expected }(), @@ -631,8 +638,9 @@ func TestDeviceRegistryDelete(t *testing.T) { }) }, SetByIDFunc: func(ctx context.Context, appID ttnpb.ApplicationIdentifiers, devID string, gets []string, f func(*ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error)) (*ttnpb.EndDevice, error) { - test.MustTFromContext(ctx).Fatal("SetByIDFunc must not be called") - panic("Unreachable") + err := errors.New("SetByIDFunc must not be called") + test.MustTFromContext(ctx).Error(err) + return nil, err }, Request: deepcopy.Copy(&ids).(*ttnpb.EndDeviceIdentifiers), ErrorAssertion: func(t *testing.T, err error) bool { @@ -670,7 +678,9 @@ func TestDeviceRegistryDelete(t *testing.T) { a.So(gets, should.BeNil) dev, sets, err := f(nil) - a.So(err, should.BeNil) + if !a.So(err, should.BeNil) { + return nil, err + } a.So(sets, should.BeNil) a.So(dev, should.BeNil) return nil, nil @@ -705,7 +715,9 @@ func TestDeviceRegistryDelete(t *testing.T) { dev, sets, err := f(&ttnpb.EndDevice{ EndDeviceIdentifiers: ids, }) - a.So(err, should.BeNil) + if !a.So(err, should.BeNil) { + return nil, err + } a.So(sets, should.BeNil) a.So(dev, should.BeNil) return nil, nil From 31faaf1cdb2f51b0fc5de2125e61587bb7eed57c Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 20 Feb 2019 19:22:14 +0100 Subject: [PATCH 37/40] ns: Use EndDeviceIdentifiers directly in registry tests --- pkg/networkserver/grpc_deviceregistry_test.go | 177 ++++++++++-------- 1 file changed, 104 insertions(+), 73 deletions(-) diff --git a/pkg/networkserver/grpc_deviceregistry_test.go b/pkg/networkserver/grpc_deviceregistry_test.go index 29f946cf06..563484fa46 100644 --- a/pkg/networkserver/grpc_deviceregistry_test.go +++ b/pkg/networkserver/grpc_deviceregistry_test.go @@ -38,13 +38,6 @@ import ( func TestDeviceRegistryGet(t *testing.T) { type getByIDCallKey struct{} - ids := ttnpb.EndDeviceIdentifiers{ - DeviceID: DeviceID, - ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ - ApplicationID: ApplicationID, - }, - } - for _, tc := range []struct { Name string ContextFunc func(context.Context) context.Context @@ -59,7 +52,7 @@ func TestDeviceRegistryGet(t *testing.T) { ContextFunc: func(ctx context.Context) context.Context { return rights.NewContext(ctx, rights.Rights{ ApplicationRights: map[string]*ttnpb.Rights{ - unique.ID(ctx, ids.ApplicationIdentifiers): { + unique.ID(ctx, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}): { Rights: []ttnpb.Right{ ttnpb.RIGHT_GATEWAY_SETTINGS_BASIC, }, @@ -73,7 +66,10 @@ func TestDeviceRegistryGet(t *testing.T) { return nil, err }, Request: &ttnpb.GetEndDeviceRequest{ - EndDeviceIdentifiers: ids, + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + }, FieldMask: pbtypes.FieldMask{ Paths: []string{ "test", @@ -98,7 +94,7 @@ func TestDeviceRegistryGet(t *testing.T) { ContextFunc: func(ctx context.Context) context.Context { return rights.NewContext(ctx, rights.Rights{ ApplicationRights: map[string]*ttnpb.Rights{ - unique.ID(ctx, ids.ApplicationIdentifiers): { + unique.ID(ctx, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}): { Rights: []ttnpb.Right{ ttnpb.RIGHT_APPLICATION_DEVICES_READ, }, @@ -109,17 +105,23 @@ func TestDeviceRegistryGet(t *testing.T) { GetByIDFunc: func(ctx context.Context, appID ttnpb.ApplicationIdentifiers, devID string, paths []string) (*ttnpb.EndDevice, error) { defer test.MustIncrementContextCounter(ctx, getByIDCallKey{}, 1) a := assertions.New(test.MustTFromContext(ctx)) - a.So(appID, should.Resemble, ids.ApplicationIdentifiers) - a.So(devID, should.Equal, DeviceID) + a.So(appID, should.Resemble, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}) + a.So(devID, should.Equal, "test-dev-id") a.So(paths, should.HaveSameElementsDeep, []string{ "test", }) return &ttnpb.EndDevice{ - EndDeviceIdentifiers: ids, + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + }, }, nil }, Request: &ttnpb.GetEndDeviceRequest{ - EndDeviceIdentifiers: ids, + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + }, FieldMask: pbtypes.FieldMask{ Paths: []string{ "test", @@ -127,7 +129,10 @@ func TestDeviceRegistryGet(t *testing.T) { }, }, Device: &ttnpb.EndDevice{ - EndDeviceIdentifiers: ids, + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + }, }, ContextAssertion: func(ctx context.Context) bool { a := assertions.New(test.MustTFromContext(ctx)) @@ -182,13 +187,6 @@ func TestDeviceRegistryGet(t *testing.T) { func TestDeviceRegistrySet(t *testing.T) { type setByIDCallKey struct{} - ids := ttnpb.EndDeviceIdentifiers{ - DeviceID: DeviceID, - ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ - ApplicationID: ApplicationID, - }, - } - for _, tc := range []struct { Name string ContextFunc func(context.Context) context.Context @@ -203,7 +201,7 @@ func TestDeviceRegistrySet(t *testing.T) { ContextFunc: func(ctx context.Context) context.Context { return rights.NewContext(ctx, rights.Rights{ ApplicationRights: map[string]*ttnpb.Rights{ - unique.ID(ctx, ids.ApplicationIdentifiers): { + unique.ID(ctx, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}): { Rights: []ttnpb.Right{ ttnpb.RIGHT_GATEWAY_SETTINGS_BASIC, }, @@ -218,8 +216,11 @@ func TestDeviceRegistrySet(t *testing.T) { }, Request: &ttnpb.SetEndDeviceRequest{ Device: ttnpb.EndDevice{ - EndDeviceIdentifiers: ids, - SupportsJoin: true, + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + }, + SupportsJoin: true, }, FieldMask: pbtypes.FieldMask{ Paths: []string{ @@ -254,7 +255,7 @@ func TestDeviceRegistrySet(t *testing.T) { ContextFunc: func(ctx context.Context) context.Context { return rights.NewContext(ctx, rights.Rights{ ApplicationRights: map[string]*ttnpb.Rights{ - unique.ID(ctx, ids.ApplicationIdentifiers): { + unique.ID(ctx, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}): { Rights: []ttnpb.Right{ ttnpb.RIGHT_APPLICATION_DEVICES_WRITE, }, @@ -265,8 +266,8 @@ func TestDeviceRegistrySet(t *testing.T) { SetByIDFunc: func(ctx context.Context, appID ttnpb.ApplicationIdentifiers, devID string, gets []string, f func(*ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error)) (*ttnpb.EndDevice, error) { defer test.MustIncrementContextCounter(ctx, setByIDCallKey{}, 1) a := assertions.New(test.MustTFromContext(ctx)) - a.So(appID, should.Resemble, ids.ApplicationIdentifiers) - a.So(devID, should.Equal, DeviceID) + a.So(appID, should.Resemble, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}) + a.So(devID, should.Equal, "test-dev-id") a.So(gets, should.HaveSameElementsDeep, []string{ "frequency_plan_id", "lorawan_phy_version", @@ -295,11 +296,16 @@ func TestDeviceRegistrySet(t *testing.T) { "supports_join", }) a.So(dev, should.Resemble, &ttnpb.EndDevice{ - EndDeviceIdentifiers: ids, - FrequencyPlanID: test.EUFrequencyPlanID, - LoRaWANPHYVersion: ttnpb.PHY_V1_0, - LoRaWANVersion: ttnpb.MAC_V1_0, - SupportsJoin: true, + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + JoinEUI: &types.EUI64{0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + DevEUI: &types.EUI64{0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + }, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0, + LoRaWANVersion: ttnpb.MAC_V1_0, + SupportsJoin: true, MACSettings: &ttnpb.MACSettings{ ADRMargin: &pbtypes.FloatValue{Value: 4}, }, @@ -308,11 +314,16 @@ func TestDeviceRegistrySet(t *testing.T) { }, Request: &ttnpb.SetEndDeviceRequest{ Device: ttnpb.EndDevice{ - EndDeviceIdentifiers: ids, - FrequencyPlanID: test.EUFrequencyPlanID, - LoRaWANPHYVersion: ttnpb.PHY_V1_0, - LoRaWANVersion: ttnpb.MAC_V1_0, - SupportsJoin: true, + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + JoinEUI: &types.EUI64{0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + DevEUI: &types.EUI64{0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + }, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0, + LoRaWANVersion: ttnpb.MAC_V1_0, + SupportsJoin: true, MACSettings: &ttnpb.MACSettings{ ADRMargin: &pbtypes.FloatValue{Value: 4}, }, @@ -332,11 +343,16 @@ func TestDeviceRegistrySet(t *testing.T) { }, }, Device: &ttnpb.EndDevice{ - EndDeviceIdentifiers: ids, - FrequencyPlanID: test.EUFrequencyPlanID, - LoRaWANPHYVersion: ttnpb.PHY_V1_0, - LoRaWANVersion: ttnpb.MAC_V1_0, - SupportsJoin: true, + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + JoinEUI: &types.EUI64{0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + DevEUI: &types.EUI64{0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + }, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0, + LoRaWANVersion: ttnpb.MAC_V1_0, + SupportsJoin: true, MACSettings: &ttnpb.MACSettings{ ADRMargin: &pbtypes.FloatValue{Value: 4}, }, @@ -353,7 +369,7 @@ func TestDeviceRegistrySet(t *testing.T) { ContextFunc: func(ctx context.Context) context.Context { return rights.NewContext(ctx, rights.Rights{ ApplicationRights: map[string]*ttnpb.Rights{ - unique.ID(ctx, ids.ApplicationIdentifiers): { + unique.ID(ctx, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}): { Rights: []ttnpb.Right{ ttnpb.RIGHT_APPLICATION_DEVICES_WRITE, }, @@ -364,8 +380,8 @@ func TestDeviceRegistrySet(t *testing.T) { SetByIDFunc: func(ctx context.Context, appID ttnpb.ApplicationIdentifiers, devID string, gets []string, f func(*ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error)) (*ttnpb.EndDevice, error) { defer test.MustIncrementContextCounter(ctx, setByIDCallKey{}, 1) a := assertions.New(test.MustTFromContext(ctx)) - a.So(appID, should.Resemble, ids.ApplicationIdentifiers) - a.So(devID, should.Equal, DeviceID) + a.So(appID, should.Resemble, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}) + a.So(devID, should.Equal, "test-dev-id") a.So(gets, should.HaveSameElementsDeep, []string{ "frequency_plan_id", "lorawan_phy_version", @@ -413,8 +429,10 @@ func TestDeviceRegistrySet(t *testing.T) { expected := &ttnpb.EndDevice{ EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ - DeviceID: ids.DeviceID, - ApplicationIdentifiers: ids.ApplicationIdentifiers, + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + JoinEUI: &types.EUI64{0x70, 0xB3, 0xD5, 0x95, 0x20, 0x00, 0x00, 0x00}, + DevEUI: &types.EUI64{0xA8, 0x17, 0x58, 0xFF, 0xFE, 0x03, 0x22, 0x77}, DevAddr: &types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, }, FrequencyPlanID: test.EUFrequencyPlanID, @@ -460,11 +478,17 @@ func TestDeviceRegistrySet(t *testing.T) { }, Request: &ttnpb.SetEndDeviceRequest{ Device: ttnpb.EndDevice{ - EndDeviceIdentifiers: ids, - FrequencyPlanID: test.EUFrequencyPlanID, - LoRaWANPHYVersion: ttnpb.PHY_V1_0_2_REV_B, - LoRaWANVersion: ttnpb.MAC_V1_0_2, - SupportsJoin: true, + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + JoinEUI: &types.EUI64{0x70, 0xB3, 0xD5, 0x95, 0x20, 0x00, 0x00, 0x00}, + DevEUI: &types.EUI64{0xA8, 0x17, 0x58, 0xFF, 0xFE, 0x03, 0x22, 0x77}, + DevAddr: &types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, + }, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0_2_REV_B, + LoRaWANVersion: ttnpb.MAC_V1_0_2, + SupportsJoin: true, MACSettings: &ttnpb.MACSettings{ Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, UseADR: &pbtypes.BoolValue{Value: true}, @@ -512,8 +536,10 @@ func TestDeviceRegistrySet(t *testing.T) { Device: func() *ttnpb.EndDevice { expected := &ttnpb.EndDevice{ EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ - DeviceID: ids.DeviceID, - ApplicationIdentifiers: ids.ApplicationIdentifiers, + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + JoinEUI: &types.EUI64{0x70, 0xB3, 0xD5, 0x95, 0x20, 0x00, 0x00, 0x00}, + DevEUI: &types.EUI64{0xA8, 0x17, 0x58, 0xFF, 0xFE, 0x03, 0x22, 0x77}, DevAddr: &types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, }, FrequencyPlanID: test.EUFrequencyPlanID, @@ -609,13 +635,6 @@ func TestDeviceRegistrySet(t *testing.T) { func TestDeviceRegistryDelete(t *testing.T) { type setByIDCallKey struct{} - ids := ttnpb.EndDeviceIdentifiers{ - DeviceID: DeviceID, - ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ - ApplicationID: ApplicationID, - }, - } - for _, tc := range []struct { Name string ContextFunc func(context.Context) context.Context @@ -629,7 +648,7 @@ func TestDeviceRegistryDelete(t *testing.T) { ContextFunc: func(ctx context.Context) context.Context { return rights.NewContext(ctx, rights.Rights{ ApplicationRights: map[string]*ttnpb.Rights{ - unique.ID(ctx, ids.ApplicationIdentifiers): { + unique.ID(ctx, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}): { Rights: []ttnpb.Right{ ttnpb.RIGHT_GATEWAY_SETTINGS_BASIC, }, @@ -642,7 +661,10 @@ func TestDeviceRegistryDelete(t *testing.T) { test.MustTFromContext(ctx).Error(err) return nil, err }, - Request: deepcopy.Copy(&ids).(*ttnpb.EndDeviceIdentifiers), + Request: &ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + }, ErrorAssertion: func(t *testing.T, err error) bool { if !assertions.New(t).So(errors.IsPermissionDenied(err), should.BeTrue) { t.Errorf("Received error: %s", err) @@ -661,7 +683,7 @@ func TestDeviceRegistryDelete(t *testing.T) { ContextFunc: func(ctx context.Context) context.Context { return rights.NewContext(ctx, rights.Rights{ ApplicationRights: map[string]*ttnpb.Rights{ - unique.ID(ctx, ids.ApplicationIdentifiers): { + unique.ID(ctx, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}): { Rights: []ttnpb.Right{ ttnpb.RIGHT_APPLICATION_DEVICES_WRITE, }, @@ -673,8 +695,8 @@ func TestDeviceRegistryDelete(t *testing.T) { defer test.MustIncrementContextCounter(ctx, setByIDCallKey{}, 1) t := test.MustTFromContext(ctx) a := assertions.New(t) - a.So(appID, should.Resemble, ids.ApplicationIdentifiers) - a.So(devID, should.Equal, DeviceID) + a.So(appID, should.Resemble, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}) + a.So(devID, should.Equal, "test-dev-id") a.So(gets, should.BeNil) dev, sets, err := f(nil) @@ -685,7 +707,10 @@ func TestDeviceRegistryDelete(t *testing.T) { a.So(dev, should.BeNil) return nil, nil }, - Request: deepcopy.Copy(&ids).(*ttnpb.EndDeviceIdentifiers), + Request: &ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + }, ContextAssertion: func(ctx context.Context) bool { a := assertions.New(test.MustTFromContext(ctx)) return a.So(test.MustCounterFromContext(ctx, setByIDCallKey{}), should.Equal, 1) @@ -697,7 +722,7 @@ func TestDeviceRegistryDelete(t *testing.T) { ContextFunc: func(ctx context.Context) context.Context { return rights.NewContext(ctx, rights.Rights{ ApplicationRights: map[string]*ttnpb.Rights{ - unique.ID(ctx, ids.ApplicationIdentifiers): { + unique.ID(ctx, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}): { Rights: []ttnpb.Right{ ttnpb.RIGHT_APPLICATION_DEVICES_WRITE, }, @@ -708,12 +733,15 @@ func TestDeviceRegistryDelete(t *testing.T) { SetByIDFunc: func(ctx context.Context, appID ttnpb.ApplicationIdentifiers, devID string, paths []string, f func(*ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error)) (*ttnpb.EndDevice, error) { defer test.MustIncrementContextCounter(ctx, setByIDCallKey{}, 1) a := assertions.New(test.MustTFromContext(ctx)) - a.So(appID, should.Resemble, ids.ApplicationIdentifiers) - a.So(devID, should.Equal, DeviceID) + a.So(appID, should.Resemble, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}) + a.So(devID, should.Equal, "test-dev-id") a.So(paths, should.BeNil) dev, sets, err := f(&ttnpb.EndDevice{ - EndDeviceIdentifiers: ids, + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + }, }) if !a.So(err, should.BeNil) { return nil, err @@ -722,7 +750,10 @@ func TestDeviceRegistryDelete(t *testing.T) { a.So(dev, should.BeNil) return nil, nil }, - Request: deepcopy.Copy(&ids).(*ttnpb.EndDeviceIdentifiers), + Request: &ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + }, ContextAssertion: func(ctx context.Context) bool { a := assertions.New(test.MustTFromContext(ctx)) return a.So(test.MustCounterFromContext(ctx, setByIDCallKey{}), should.Equal, 1) From 516193c0f92040ec3f2951f1d8db0ee58d8048d1 Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 20 Feb 2019 19:28:27 +0100 Subject: [PATCH 38/40] ns: Remove misplaced fields in registry tests --- pkg/networkserver/grpc_deviceregistry_test.go | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/pkg/networkserver/grpc_deviceregistry_test.go b/pkg/networkserver/grpc_deviceregistry_test.go index 563484fa46..3052772565 100644 --- a/pkg/networkserver/grpc_deviceregistry_test.go +++ b/pkg/networkserver/grpc_deviceregistry_test.go @@ -230,7 +230,6 @@ func TestDeviceRegistrySet(t *testing.T) { "mac_settings.supports_32_bit_f_cnt", "mac_settings.use_adr", "resets_f_cnt", - "resets_join_nonces", "supports_class_b", "supports_class_c", "supports_join", @@ -274,7 +273,6 @@ func TestDeviceRegistrySet(t *testing.T) { "lorawan_version", "mac_settings.adr_margin", "resets_f_cnt", - "resets_join_nonces", "supports_class_b", "supports_class_c", "supports_join", @@ -290,7 +288,6 @@ func TestDeviceRegistrySet(t *testing.T) { "lorawan_version", "mac_settings.adr_margin", "resets_f_cnt", - "resets_join_nonces", "supports_class_b", "supports_class_c", "supports_join", @@ -335,7 +332,6 @@ func TestDeviceRegistrySet(t *testing.T) { "lorawan_version", "mac_settings.adr_margin", "resets_f_cnt", - "resets_join_nonces", "supports_class_b", "supports_class_c", "supports_join", @@ -389,10 +385,7 @@ func TestDeviceRegistrySet(t *testing.T) { "mac_settings.use_adr", "mac_settings.supports_32_bit_f_cnt", "resets_f_cnt", - "resets_join_nonces", - "root_keys.app_key.key", "session.dev_addr", - "session.keys.app_s_key.key", "session.keys.f_nwk_s_int_key.key", "session.last_f_cnt_up", "session.last_n_f_cnt_down", @@ -412,10 +405,7 @@ func TestDeviceRegistrySet(t *testing.T) { "mac_settings.use_adr", "mac_state", "resets_f_cnt", - "resets_join_nonces", - "root_keys.app_key.key", "session.dev_addr", - "session.keys.app_s_key.key", "session.keys.f_nwk_s_int_key.key", "session.keys.nwk_s_enc_key.kek_label", "session.keys.nwk_s_enc_key.key", @@ -443,20 +433,12 @@ func TestDeviceRegistrySet(t *testing.T) { Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, UseADR: &pbtypes.BoolValue{Value: true}, }, - RootKeys: &ttnpb.RootKeys{ - AppKey: &ttnpb.KeyEnvelope{ - Key: []byte{0x4f, 0x93, 0x95, 0x95, 0xce, 0x83, 0x28, 0x8a, 0xfe, 0xf8, 0x1b, 0xd8, 0x81, 0xc3, 0xc3, 0x6e}, - }, - }, Session: &ttnpb.Session{ StartedAt: time.Unix(0, 42).UTC(), DevAddr: types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, LastFCntUp: 45872, LastNFCntDown: 1880, SessionKeys: ttnpb.SessionKeys{ - AppSKey: &ttnpb.KeyEnvelope{ - Key: []byte{0xa1, 0x5b, 0xef, 0x4a, 0x32, 0x33, 0x27, 0x4a, 0xe9, 0x17, 0xe4, 0xaf, 0xb1, 0x90, 0x55, 0xf2}, - }, FNwkSIntKey: &ttnpb.KeyEnvelope{ Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, }, @@ -493,20 +475,12 @@ func TestDeviceRegistrySet(t *testing.T) { Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, UseADR: &pbtypes.BoolValue{Value: true}, }, - RootKeys: &ttnpb.RootKeys{ - AppKey: &ttnpb.KeyEnvelope{ - Key: []byte{0x4f, 0x93, 0x95, 0x95, 0xce, 0x83, 0x28, 0x8a, 0xfe, 0xf8, 0x1b, 0xd8, 0x81, 0xc3, 0xc3, 0x6e}, - }, - }, Session: &ttnpb.Session{ StartedAt: time.Unix(0, 42).UTC(), DevAddr: types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, LastFCntUp: 45872, LastNFCntDown: 1880, SessionKeys: ttnpb.SessionKeys{ - AppSKey: &ttnpb.KeyEnvelope{ - Key: []byte{0xa1, 0x5b, 0xef, 0x4a, 0x32, 0x33, 0x27, 0x4a, 0xe9, 0x17, 0xe4, 0xaf, 0xb1, 0x90, 0x55, 0xf2}, - }, FNwkSIntKey: &ttnpb.KeyEnvelope{ Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, }, @@ -521,10 +495,7 @@ func TestDeviceRegistrySet(t *testing.T) { "mac_settings.use_adr", "mac_settings.supports_32_bit_f_cnt", "resets_f_cnt", - "resets_join_nonces", - "root_keys.app_key.key", "session.dev_addr", - "session.keys.app_s_key.key", "session.keys.f_nwk_s_int_key.key", "session.last_f_cnt_up", "session.last_n_f_cnt_down", @@ -550,9 +521,6 @@ func TestDeviceRegistrySet(t *testing.T) { Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, UseADR: &pbtypes.BoolValue{Value: true}, }, - RootKeys: &ttnpb.RootKeys{ - AppKey: &ttnpb.KeyEnvelope{ - Key: []byte{0x4f, 0x93, 0x95, 0x95, 0xce, 0x83, 0x28, 0x8a, 0xfe, 0xf8, 0x1b, 0xd8, 0x81, 0xc3, 0xc3, 0x6e}, }, }, Session: &ttnpb.Session{ @@ -561,8 +529,6 @@ func TestDeviceRegistrySet(t *testing.T) { LastFCntUp: 45872, LastNFCntDown: 1880, SessionKeys: ttnpb.SessionKeys{ - AppSKey: &ttnpb.KeyEnvelope{ - Key: []byte{0xa1, 0x5b, 0xef, 0x4a, 0x32, 0x33, 0x27, 0x4a, 0xe9, 0x17, 0xe4, 0xaf, 0xb1, 0x90, 0x55, 0xf2}, }, FNwkSIntKey: &ttnpb.KeyEnvelope{ Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, From 69a9b2e7ebdb92bd170ca742a7e8c56c908950fc Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 20 Feb 2019 19:40:54 +0100 Subject: [PATCH 39/40] ns: Add additional registry create test cases --- pkg/networkserver/grpc_deviceregistry_test.go | 366 ++++++++++++++++++ 1 file changed, 366 insertions(+) diff --git a/pkg/networkserver/grpc_deviceregistry_test.go b/pkg/networkserver/grpc_deviceregistry_test.go index 3052772565..8f106867b5 100644 --- a/pkg/networkserver/grpc_deviceregistry_test.go +++ b/pkg/networkserver/grpc_deviceregistry_test.go @@ -521,15 +521,381 @@ func TestDeviceRegistrySet(t *testing.T) { Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, UseADR: &pbtypes.BoolValue{Value: true}, }, + Session: &ttnpb.Session{ + StartedAt: time.Unix(0, 42).UTC(), + DevAddr: types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, + LastFCntUp: 45872, + LastNFCntDown: 1880, + SessionKeys: ttnpb.SessionKeys{ + FNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, + }, + NwkSEncKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, + }, + SNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, + }, + }, + }, + } + if err := ResetMACState(expected, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{}); err != nil { + panic(fmt.Sprintf("Failed to reset MAC state: %s", err)) + } + return expected + }(), + ContextAssertion: func(ctx context.Context) bool { + a := assertions.New(test.MustTFromContext(ctx)) + return a.So(test.MustCounterFromContext(ctx, setByIDCallKey{}), should.Equal, 1) + }, + }, + + { + Name: "Create ABP device", + ContextFunc: func(ctx context.Context) context.Context { + return rights.NewContext(ctx, rights.Rights{ + ApplicationRights: map[string]*ttnpb.Rights{ + unique.ID(ctx, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}): { + Rights: []ttnpb.Right{ + ttnpb.RIGHT_APPLICATION_DEVICES_WRITE, + }, + }, + }, + }) + }, + SetByIDFunc: func(ctx context.Context, appID ttnpb.ApplicationIdentifiers, devID string, gets []string, f func(*ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error)) (*ttnpb.EndDevice, error) { + defer test.MustIncrementContextCounter(ctx, setByIDCallKey{}, 1) + a := assertions.New(test.MustTFromContext(ctx)) + a.So(appID, should.Resemble, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}) + a.So(devID, should.Equal, "test-dev-id") + a.So(gets, should.HaveSameElementsDeep, []string{ + "frequency_plan_id", + "lorawan_phy_version", + "lorawan_version", + "mac_settings.use_adr", + "mac_settings.supports_32_bit_f_cnt", + "resets_f_cnt", + "session.dev_addr", + "session.keys.f_nwk_s_int_key.key", + "session.last_f_cnt_up", + "session.last_n_f_cnt_down", + "session.started_at", + "supports_join", + }) + + dev, sets, err := f(nil) + if !a.So(err, should.BeNil) { + return nil, err + } + a.So(sets, should.HaveSameElementsDeep, []string{ + "frequency_plan_id", + "lorawan_phy_version", + "lorawan_version", + "mac_settings.supports_32_bit_f_cnt", + "mac_settings.use_adr", + "mac_state", + "resets_f_cnt", + "session.dev_addr", + "session.keys.f_nwk_s_int_key.key", + "session.keys.nwk_s_enc_key.kek_label", + "session.keys.nwk_s_enc_key.key", + "session.keys.s_nwk_s_int_key.kek_label", + "session.keys.s_nwk_s_int_key.key", + "session.last_f_cnt_up", + "session.last_n_f_cnt_down", + "session.started_at", + "supports_join", + }) + + expected := &ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + DevAddr: &types.DevAddr{0x42, 0x00, 0x00, 0x00}, + }, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0_2_REV_B, + LoRaWANVersion: ttnpb.MAC_V1_0_2, + MACSettings: &ttnpb.MACSettings{ + Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, + UseADR: &pbtypes.BoolValue{Value: true}, + }, + Session: &ttnpb.Session{ + StartedAt: time.Unix(0, 42).UTC(), + DevAddr: types.DevAddr{0x42, 0x00, 0x00, 0x00}, + LastFCntUp: 42, + LastNFCntDown: 4242, + SessionKeys: ttnpb.SessionKeys{ + FNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x42, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + }, + NwkSEncKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x42, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + }, + SNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x42, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + }, + }, + }, + } + err = ResetMACState(expected, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{}) + if !a.So(err, should.BeNil) { + panic(fmt.Sprintf("Failed to reset MAC state: %s", err)) + } + a.So(dev, should.Resemble, expected) + return dev, nil + }, + Request: &ttnpb.SetEndDeviceRequest{ + Device: ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + DevAddr: &types.DevAddr{0x42, 0x00, 0x00, 0x00}, + }, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0_2_REV_B, + LoRaWANVersion: ttnpb.MAC_V1_0_2, + MACSettings: &ttnpb.MACSettings{ + Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, + UseADR: &pbtypes.BoolValue{Value: true}, + }, + Session: &ttnpb.Session{ + StartedAt: time.Unix(0, 42).UTC(), + DevAddr: types.DevAddr{0x42, 0x00, 0x00, 0x00}, + LastFCntUp: 42, + LastNFCntDown: 4242, + SessionKeys: ttnpb.SessionKeys{ + FNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x42, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + }, + }, + }, + }, + FieldMask: pbtypes.FieldMask{ + Paths: []string{ + "frequency_plan_id", + "lorawan_phy_version", + "lorawan_version", + "mac_settings.use_adr", + "mac_settings.supports_32_bit_f_cnt", + "resets_f_cnt", + "session.dev_addr", + "session.keys.f_nwk_s_int_key.key", + "session.last_f_cnt_up", + "session.last_n_f_cnt_down", + "session.started_at", + "supports_join", + }, + }, + }, + Device: func() *ttnpb.EndDevice { + expected := &ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + DevAddr: &types.DevAddr{0x42, 0x00, 0x00, 0x00}, + }, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0_2_REV_B, + LoRaWANVersion: ttnpb.MAC_V1_0_2, + MACSettings: &ttnpb.MACSettings{ + Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, + UseADR: &pbtypes.BoolValue{Value: true}, + }, + Session: &ttnpb.Session{ + StartedAt: time.Unix(0, 42).UTC(), + DevAddr: types.DevAddr{0x42, 0x00, 0x00, 0x00}, + LastFCntUp: 42, + LastNFCntDown: 4242, + SessionKeys: ttnpb.SessionKeys{ + FNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x42, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + }, + NwkSEncKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x42, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + }, + SNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x42, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + }, + }, + }, + } + if err := ResetMACState(expected, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{}); err != nil { + panic(fmt.Sprintf("Failed to reset MAC state: %s", err)) + } + return expected + }(), + ContextAssertion: func(ctx context.Context) bool { + a := assertions.New(test.MustTFromContext(ctx)) + return a.So(test.MustCounterFromContext(ctx, setByIDCallKey{}), should.Equal, 1) + }, + }, + + { + // https://github.com/TheThingsNetwork/lorawan-stack/issues/159#issue-411803325 + Name: "Create ABP device with existing session", + ContextFunc: func(ctx context.Context) context.Context { + return rights.NewContext(ctx, rights.Rights{ + ApplicationRights: map[string]*ttnpb.Rights{ + unique.ID(ctx, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}): { + Rights: []ttnpb.Right{ + ttnpb.RIGHT_APPLICATION_DEVICES_WRITE, + }, + }, + }, + }) + }, + SetByIDFunc: func(ctx context.Context, appID ttnpb.ApplicationIdentifiers, devID string, gets []string, f func(*ttnpb.EndDevice) (*ttnpb.EndDevice, []string, error)) (*ttnpb.EndDevice, error) { + defer test.MustIncrementContextCounter(ctx, setByIDCallKey{}, 1) + a := assertions.New(test.MustTFromContext(ctx)) + a.So(appID, should.Resemble, ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}) + a.So(devID, should.Equal, "test-dev-id") + a.So(gets, should.HaveSameElementsDeep, []string{ + "frequency_plan_id", + "lorawan_phy_version", + "lorawan_version", + "mac_settings.use_adr", + "mac_settings.supports_32_bit_f_cnt", + "resets_f_cnt", + "session.dev_addr", + "session.keys.f_nwk_s_int_key.key", + "session.last_f_cnt_up", + "session.last_n_f_cnt_down", + "session.started_at", + "supports_join", + }) + + dev, sets, err := f(nil) + if !a.So(err, should.BeNil) { + return nil, err + } + a.So(sets, should.HaveSameElementsDeep, []string{ + "frequency_plan_id", + "lorawan_phy_version", + "lorawan_version", + "mac_settings.supports_32_bit_f_cnt", + "mac_settings.use_adr", + "mac_state", + "resets_f_cnt", + "session.dev_addr", + "session.keys.f_nwk_s_int_key.key", + "session.keys.nwk_s_enc_key.kek_label", + "session.keys.nwk_s_enc_key.key", + "session.keys.s_nwk_s_int_key.kek_label", + "session.keys.s_nwk_s_int_key.key", + "session.last_f_cnt_up", + "session.last_n_f_cnt_down", + "session.started_at", + "supports_join", + }) + + expected := &ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + JoinEUI: &types.EUI64{0x70, 0xB3, 0xD5, 0x95, 0x20, 0x00, 0x00, 0x00}, + DevEUI: &types.EUI64{0xA8, 0x17, 0x58, 0xFF, 0xFE, 0x03, 0x22, 0x77}, + DevAddr: &types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, + }, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0_2_REV_B, + LoRaWANVersion: ttnpb.MAC_V1_0_2, + MACSettings: &ttnpb.MACSettings{ + Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, + UseADR: &pbtypes.BoolValue{Value: true}, + }, + Session: &ttnpb.Session{ + StartedAt: time.Unix(0, 42).UTC(), + DevAddr: types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, + LastFCntUp: 45872, + LastNFCntDown: 1880, + SessionKeys: ttnpb.SessionKeys{ + FNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, + }, + NwkSEncKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, + }, + SNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, + }, }, }, + } + err = ResetMACState(expected, frequencyplans.NewStore(test.FrequencyPlansFetcher), ttnpb.MACSettings{}) + if !a.So(err, should.BeNil) { + panic(fmt.Sprintf("Failed to reset MAC state: %s", err)) + } + a.So(dev, should.Resemble, expected) + return dev, nil + }, + Request: &ttnpb.SetEndDeviceRequest{ + Device: ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + JoinEUI: &types.EUI64{0x70, 0xB3, 0xD5, 0x95, 0x20, 0x00, 0x00, 0x00}, + DevEUI: &types.EUI64{0xA8, 0x17, 0x58, 0xFF, 0xFE, 0x03, 0x22, 0x77}, + DevAddr: &types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, + }, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0_2_REV_B, + LoRaWANVersion: ttnpb.MAC_V1_0_2, + MACSettings: &ttnpb.MACSettings{ + Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, + UseADR: &pbtypes.BoolValue{Value: true}, + }, Session: &ttnpb.Session{ StartedAt: time.Unix(0, 42).UTC(), DevAddr: types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, LastFCntUp: 45872, LastNFCntDown: 1880, SessionKeys: ttnpb.SessionKeys{ + FNwkSIntKey: &ttnpb.KeyEnvelope{ + Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, }, + }, + }, + }, + FieldMask: pbtypes.FieldMask{ + Paths: []string{ + "frequency_plan_id", + "lorawan_phy_version", + "lorawan_version", + "mac_settings.use_adr", + "mac_settings.supports_32_bit_f_cnt", + "resets_f_cnt", + "session.dev_addr", + "session.keys.f_nwk_s_int_key.key", + "session.last_f_cnt_up", + "session.last_n_f_cnt_down", + "session.started_at", + "supports_join", + }, + }, + }, + Device: func() *ttnpb.EndDevice { + expected := &ttnpb.EndDevice{ + EndDeviceIdentifiers: ttnpb.EndDeviceIdentifiers{ + DeviceID: "test-dev-id", + ApplicationIdentifiers: ttnpb.ApplicationIdentifiers{ApplicationID: "test-app-id"}, + JoinEUI: &types.EUI64{0x70, 0xB3, 0xD5, 0x95, 0x20, 0x00, 0x00, 0x00}, + DevEUI: &types.EUI64{0xA8, 0x17, 0x58, 0xFF, 0xFE, 0x03, 0x22, 0x77}, + DevAddr: &types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, + }, + FrequencyPlanID: test.EUFrequencyPlanID, + LoRaWANPHYVersion: ttnpb.PHY_V1_0_2_REV_B, + LoRaWANVersion: ttnpb.MAC_V1_0_2, + MACSettings: &ttnpb.MACSettings{ + Supports32BitFCnt: &pbtypes.BoolValue{Value: true}, + UseADR: &pbtypes.BoolValue{Value: true}, + }, + Session: &ttnpb.Session{ + StartedAt: time.Unix(0, 42).UTC(), + DevAddr: types.DevAddr{0x01, 0x0b, 0x60, 0x0c}, + LastFCntUp: 45872, + LastNFCntDown: 1880, + SessionKeys: ttnpb.SessionKeys{ FNwkSIntKey: &ttnpb.KeyEnvelope{ Key: []byte{0x9e, 0x2f, 0xb6, 0x1d, 0x73, 0x10, 0xc9, 0x27, 0x98, 0x86, 0xdb, 0x79, 0xfa, 0x52, 0xf9, 0xf4}, }, From 49745185ff99a17b2f4d2254019c05634e38a87a Mon Sep 17 00:00:00 2001 From: Roman Volosatovs Date: Wed, 20 Feb 2019 21:05:27 +0100 Subject: [PATCH 40/40] ns,cli: Specify desired Rx1 delay in config --- cmd/internal/shared/networkserver/config.go | 2 +- pkg/networkserver/config.go | 2 +- pkg/networkserver/networkserver.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/internal/shared/networkserver/config.go b/cmd/internal/shared/networkserver/config.go index 49a129b8b1..02ac69070a 100644 --- a/cmd/internal/shared/networkserver/config.go +++ b/cmd/internal/shared/networkserver/config.go @@ -32,7 +32,7 @@ var DefaultNetworkServerConfig = networkserver.Config{ }, DefaultMACSettings: networkserver.MACSettingConfig{ ADRMargin: func(v float32) *float32 { return &v }(networkserver.DefaultADRMargin), - Rx1Delay: func(v ttnpb.RxDelay) *ttnpb.RxDelay { return &v }(ttnpb.RX_DELAY_5), + DesiredRx1Delay: func(v ttnpb.RxDelay) *ttnpb.RxDelay { return &v }(ttnpb.RX_DELAY_5), ClassBTimeout: func(v time.Duration) *time.Duration { return &v }(time.Minute), ClassCTimeout: func(v time.Duration) *time.Duration { return &v }(networkserver.DefaultClassCTimeout), StatusTimePeriodicity: func(v time.Duration) *time.Duration { return &v }(networkserver.DefaultStatusTimePeriodicity), diff --git a/pkg/networkserver/config.go b/pkg/networkserver/config.go index afbf1c181a..b2428d8224 100644 --- a/pkg/networkserver/config.go +++ b/pkg/networkserver/config.go @@ -35,7 +35,7 @@ type Config struct { type MACSettingConfig struct { ADRMargin *float32 `name:"adr-margin" description:"The default margin Network Server should add in ADR requests if not configured in device's MAC settings"` - Rx1Delay *ttnpb.RxDelay `name:"rx1-delay" description:"Rx1Delay value Network Server should use if not configured in device's MAC settings"` + DesiredRx1Delay *ttnpb.RxDelay `name:"desired-rx1-delay" description:"Desired Rx1Delay value Network Server should use if not configured in device's MAC settings"` ClassBTimeout *time.Duration `name:"class-b-timeout" description:"Deadline for a device in class B mode to respond to requests from the Network Server if not configured in device's MAC settings"` ClassCTimeout *time.Duration `name:"class-c-timeout" description:"Deadline for a device in class C mode to respond to requests from the Network Server if not configured in device's MAC settings"` StatusTimePeriodicity *time.Duration `name:"status-time-periodicity" description:"The interval after which a DevStatusReq MACCommand shall be sent by Network Server if not configured in device's MAC settings"` diff --git a/pkg/networkserver/networkserver.go b/pkg/networkserver/networkserver.go index 0ea22cf845..a4c7d4fcf6 100644 --- a/pkg/networkserver/networkserver.go +++ b/pkg/networkserver/networkserver.go @@ -225,8 +225,8 @@ func New(c *component.Component, conf *Config, opts ...Option) (*NetworkServer, if conf.DefaultMACSettings.ADRMargin != nil { ns.defaultMACSettings.ADRMargin = &pbtypes.FloatValue{Value: *conf.DefaultMACSettings.ADRMargin} } - if conf.DefaultMACSettings.Rx1Delay != nil { - ns.defaultMACSettings.Rx1Delay = &ttnpb.MACSettings_RxDelayValue{Value: *conf.DefaultMACSettings.Rx1Delay} + if conf.DefaultMACSettings.DesiredRx1Delay != nil { + ns.defaultMACSettings.DesiredRx1Delay = &ttnpb.MACSettings_RxDelayValue{Value: *conf.DefaultMACSettings.DesiredRx1Delay} } if conf.DefaultMACSettings.StatusCountPeriodicity != nil { ns.defaultMACSettings.StatusCountPeriodicity = &pbtypes.UInt32Value{Value: *conf.DefaultMACSettings.StatusCountPeriodicity}